From d0ba38d9ee000c486a2b178e677c2b28723d89cb Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 19 Nov 2013 10:58:58 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@6491 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/rt/ports/ARMCMx/compilers/GCC/chtypes.h | 45 +++- os/rt/ports/e200/chcore.c | 112 ++++++++ os/rt/ports/e200/chcore.h | 404 +++++++++++++++++++++++++++++ os/rt/ports/e200/compilers/GCC/chtypes.h | 106 ++++++++ 4 files changed, 653 insertions(+), 14 deletions(-) create mode 100644 os/rt/ports/e200/chcore.c create mode 100644 os/rt/ports/e200/chcore.h create mode 100644 os/rt/ports/e200/compilers/GCC/chtypes.h (limited to 'os/rt') diff --git a/os/rt/ports/ARMCMx/compilers/GCC/chtypes.h b/os/rt/ports/ARMCMx/compilers/GCC/chtypes.h index 61052a46d..864e05522 100644 --- a/os/rt/ports/ARMCMx/compilers/GCC/chtypes.h +++ b/os/rt/ports/ARMCMx/compilers/GCC/chtypes.h @@ -51,20 +51,37 @@ #endif /** @} */ -typedef uint32_t rtcnt_t; /**< Realtime counter. */ -typedef uint64_t rttime_t; /**< Time accumulator. */ -typedef uint32_t syssts_t; /**< System status word. */ -typedef uint8_t tmode_t; /**< Thread flags. */ -typedef uint8_t tstate_t; /**< Thread state. */ -typedef uint8_t trefs_t; /**< Thread references counter. */ -typedef uint8_t tslices_t; /**< Thread time slices counter. */ -typedef uint32_t tprio_t; /**< Thread priority. */ -typedef int32_t msg_t; /**< Inter-thread message. */ -typedef int32_t eventid_t; /**< Numeric event identifier. */ -typedef uint32_t eventmask_t; /**< Mask of event identifiers. */ -typedef uint32_t eventflags_t; /**< Mask of event flags. */ -typedef int32_t cnt_t; /**< Generic signed counter. */ -typedef uint32_t ucnt_t; /**< Generic unsigned counter. */ +/** + * @name Derived generic types + * @{ + */ +typedef volatile int8_t vint8_t; /**< Volatile signed 8 bits. */ +typedef volatile uint8_t vuint8_t; /**< Volatile unsigned 8 bits. */ +typedef volatile int16_t vint16_t; /**< Volatile signed 16 bits. */ +typedef volatile uint16_t vuint16_t; /**< Volatile unsigned 16 bits. */ +typedef volatile int32_t vint32_t; /**< Volatile signed 32 bits. */ +typedef volatile uint32_t vuint32_t; /**< Volatile unsigned 32 bits. */ +/** @} */ + +/** + * @name Kernel types + * @{ + */ +typedef uint32_t rtcnt_t; /**< Realtime counter. */ +typedef uint64_t rttime_t; /**< Realtime accumulator. */ +typedef uint32_t syssts_t; /**< System status word. */ +typedef uint8_t tmode_t; /**< Thread flags. */ +typedef uint8_t tstate_t; /**< Thread state. */ +typedef uint8_t trefs_t; /**< Thread references counter. */ +typedef uint8_t tslices_t; /**< Thread time slices counter.*/ +typedef uint32_t tprio_t; /**< Thread priority. */ +typedef int32_t msg_t; /**< Inter-thread message. */ +typedef int32_t eventid_t; /**< Numeric event identifier. */ +typedef uint32_t eventmask_t; /**< Mask of event identifiers. */ +typedef uint32_t eventflags_t; /**< Mask of event flags. */ +typedef int32_t cnt_t; /**< Generic signed counter. */ +typedef uint32_t ucnt_t; /**< Generic unsigned counter. */ +/** @} */ /** * @brief ROM constant modifier. diff --git a/os/rt/ports/e200/chcore.c b/os/rt/ports/e200/chcore.c new file mode 100644 index 000000000..4644376cf --- /dev/null +++ b/os/rt/ports/e200/chcore.c @@ -0,0 +1,112 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011,2012,2013 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file PPC/chcore.c + * @brief PowerPC architecture port code. + * + * @addtogroup PPC_CORE + * @{ + */ + +#include "ch.h" + +/** + * @brief Kernel port layer initialization. + * @details IVOR4 and IVOR10 initialization. + */ +void port_init(void) { +#if PPC_SUPPORTS_IVORS + /* The CPU supports IVOR registers, the kernel requires IVOR4 and IVOR10 + and the initialization is performed here.*/ + asm volatile ("li %%r3, _IVOR4@l \t\n" + "mtIVOR4 %%r3 \t\n" + "li %%r3, _IVOR10@l \t\n" + "mtIVOR10 %%r3" : : : "memory"); +#endif +} + +/** + * @brief Halts the system. + * @details This function is invoked by the operating system when an + * unrecoverable error is detected (for example because a programming + * error in the application code that triggers an assertion while + * in debug mode). + */ +void port_halt(void) { + + port_disable(); + while (TRUE) { + } +} + +/** + * @brief Performs a context switch between two threads. + * @details This is the most critical code in any port, this function + * is responsible for the context switch between 2 threads. + * @note The implementation of this code affects directly the context + * switch performance so optimize here as much as you can. + */ +#if !defined(__DOXYGEN__) +__attribute__((naked)) +#endif +void port_dummy1(void) { + + asm (".global _port_switch"); + asm ("_port_switch:"); + asm ("subi %sp, %sp, 80"); /* Size of the intctx structure. */ + asm ("mflr %r0"); + asm ("stw %r0, 84(%sp)"); /* LR into the caller frame. */ + asm ("mfcr %r0"); + asm ("stw %r0, 0(%sp)"); /* CR. */ + asm ("stmw %r14, 4(%sp)"); /* GPR14...GPR31. */ + + asm ("stw %sp, 12(%r4)"); /* Store swapped-out stack. */ + asm ("lwz %sp, 12(%r3)"); /* Load swapped-in stack. */ + + asm ("lmw %r14, 4(%sp)"); /* GPR14...GPR31. */ + asm ("lwz %r0, 0(%sp)"); /* CR. */ + asm ("mtcr %r0"); + asm ("lwz %r0, 84(%sp)"); /* LR from the caller frame. */ + asm ("mtlr %r0"); + asm ("addi %sp, %sp, 80"); /* Size of the intctx structure. */ + asm ("blr"); +} + +/** + * @brief Start a thread by invoking its work function. + * @details If the work function returns @p chThdExit() is automatically + * invoked. + */ +#if !defined(__DOXYGEN__) +__attribute__((naked)) +#endif +void port_dummy2(void) { + + asm (".global _port_thread_start"); + asm ("_port_thread_start:"); + chSysUnlock(); + asm ("mr %r3, %r31"); /* Thread parameter. */ + asm ("mtctr %r30"); + asm ("bctrl"); /* Invoke thread function. */ + asm ("bl chThdExit"); /* Thread termination on exit. */ +} + +/** @} */ diff --git a/os/rt/ports/e200/chcore.h b/os/rt/ports/e200/chcore.h new file mode 100644 index 000000000..b689026e5 --- /dev/null +++ b/os/rt/ports/e200/chcore.h @@ -0,0 +1,404 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011,2012,2013 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file PPC/chcore.h + * @brief PowerPC architecture port macros and structures. + * + * @addtogroup PPC_CORE + * @{ + */ + +#ifndef _CHCORE_H_ +#define _CHCORE_H_ + +#if CH_DBG_ENABLE_STACK_CHECK +#error "option CH_DBG_ENABLE_STACK_CHECK not supported by this port" +#endif + +/*===========================================================================*/ +/* Port constants (common). */ +/*===========================================================================*/ + +/* Added to make the header stand-alone when included from asm.*/ +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE (!FALSE) +#endif + +/** + * @name Supported core variants + * @{ + */ +#define PPC_VARIANT_e200z0 200 +#define PPC_VARIANT_e200z3 203 +#define PPC_VARIANT_e200z4 204 +/** @} */ + +#include "vectors.h" +#include "ppcparams.h" + +/*===========================================================================*/ +/* Port macros (common). */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Port configurable parameters (common). */ +/*===========================================================================*/ + +/** + * @brief Use VLE instruction set. + * @note This parameter is usually set in the Makefile. + */ +#if !defined(PPC_USE_VLE) +#define PPC_USE_VLE TRUE +#endif + +/** + * @brief Enables the use of the @p WFI instruction. + */ +#if !defined(PPC_ENABLE_WFI_IDLE) +#define PPC_ENABLE_WFI_IDLE FALSE +#endif + +/*===========================================================================*/ +/* Port derived parameters (common). */ +/*===========================================================================*/ + +#if PPC_USE_VLE && !PPC_SUPPORTS_VLE +#error "the selected MCU does not support VLE instructions set" +#endif + +#if !PPC_USE_VLE && !PPC_SUPPORTS_BOOKE +#error "the selected MCU does not support BookE instructions set" +#endif + +/*===========================================================================*/ +/* Port exported info (common). */ +/*===========================================================================*/ + +/** + * @brief Unique macro for the implemented architecture. + */ +#define CH_ARCHITECTURE_PPC + +/** + * @brief Name of the implemented architecture. + */ +#define CH_ARCHITECTURE_NAME "Power Architecture" + +/** + * @brief Name of the architecture variant. + */ +#if (PPC_VARIANT == PPC_VARIANT_e200z0) || defined(__DOXYGEN__) +#define CH_CORE_VARIANT_NAME "e200z0" +#elif PPC_VARIANT == PPC_VARIANT_e200z3 +#define CH_CORE_VARIANT_NAME "e200z3" +#elif PPC_VARIANT == PPC_VARIANT_e200z4 +#define CH_CORE_VARIANT_NAME "e200z4" +#else +#error "unknown or unsupported PowerPC variant specified" +#endif + +/** + * @brief Name of the compiler supported by this port. + */ +#define CH_COMPILER_NAME "GCC " __VERSION__ + +/** + * @brief Port-specific information string. + */ +#if PPC_USE_VLE +#define CH_PORT_INFO "VLE mode" +#else +#define CH_PORT_INFO "Book-E mode" +#endif + +/*===========================================================================*/ +/* Port implementation part (common). */ +/*===========================================================================*/ + +#if !defined(_FROM_ASM_) + +/** + * @brief Base type for stack and memory alignment. + */ +typedef struct { + uint8_t a[8]; +} stkalign_t __attribute__((aligned(8))); + +/** + * @brief Generic PPC register. + */ +typedef void *regppc_t; + +/** + * @brief Mandatory part of a stack frame. + */ +struct eabi_frame { + regppc_t slink; /**< Stack back link. */ + regppc_t shole; /**< Stack hole for LR storage. */ +}; + +/** + * @brief Interrupt saved context. + * @details This structure represents the stack frame saved during a + * preemption-capable interrupt handler. + * @note R2 and R13 are not saved because those are assumed to be immutable + * during the system life cycle. + */ +struct extctx { + struct eabi_frame frame; + /* Start of the e_stmvsrrw frame (offset 8).*/ + regppc_t pc; + regppc_t msr; + /* Start of the e_stmvsprw frame (offset 16).*/ + regppc_t cr; + regppc_t lr; + regppc_t ctr; + regppc_t xer; + /* Start of the e_stmvgprw frame (offset 32).*/ + regppc_t r0; + regppc_t r3; + regppc_t r4; + regppc_t r5; + regppc_t r6; + regppc_t r7; + regppc_t r8; + regppc_t r9; + regppc_t r10; + regppc_t r11; + regppc_t r12; + regppc_t padding; + }; + + /** + * @brief System saved context. + * @details This structure represents the inner stack frame during a context + * switching. + * @note R2 and R13 are not saved because those are assumed to be immutable + * during the system life cycle. + * @note LR is stored in the caller contex so it is not present in this + * structure. + */ +struct intctx { + regppc_t cr; /* Part of it is not volatile... */ + regppc_t r14; + regppc_t r15; + regppc_t r16; + regppc_t r17; + regppc_t r18; + regppc_t r19; + regppc_t r20; + regppc_t r21; + regppc_t r22; + regppc_t r23; + regppc_t r24; + regppc_t r25; + regppc_t r26; + regppc_t r27; + regppc_t r28; + regppc_t r29; + regppc_t r30; + regppc_t r31; + regppc_t padding; +}; + +/** + * @brief Platform dependent part of the @p Thread structure. + * @details This structure usually contains just the saved stack pointer + * defined as a pointer to a @p intctx structure. + */ +struct context { + struct intctx *sp; +}; + +/** + * @brief Platform dependent part of the @p chThdCreateI() API. + * @details This code usually setup the context switching frame represented + * by an @p intctx structure. + */ +#define SETUP_CONTEXT(workspace, wsize, pf, arg) { \ + uint8_t *sp = (uint8_t *)workspace + wsize - sizeof(struct eabi_frame); \ + ((struct eabi_frame *)sp)->slink = 0; \ + ((struct eabi_frame *)sp)->shole = _port_thread_start; \ + tp->p_ctx.sp = (struct intctx *)(sp - sizeof(struct intctx)); \ + tp->p_ctx.sp->r31 = arg; \ + tp->p_ctx.sp->r30 = pf; \ +} + +/** + * @brief Stack size for the system idle thread. + * @details This size depends on the idle thread implementation, usually + * the idle thread should take no more space than those reserved + * by @p PORT_INT_REQUIRED_STACK. + */ +#ifndef PORT_IDLE_THREAD_STACK_SIZE +#define PORT_IDLE_THREAD_STACK_SIZE 32 +#endif + +/** + * @brief Per-thread stack overhead for interrupts servicing. + * @details This constant is used in the calculation of the correct working + * area size. + */ +#ifndef PORT_INT_REQUIRED_STACK +#define PORT_INT_REQUIRED_STACK 256 +#endif + +/** + * @brief Enforces a correct alignment for a stack area size value. + */ +#define STACK_ALIGN(n) ((((n) - 1) | (sizeof(stkalign_t) - 1)) + 1) + +/** + * @brief Computes the thread working area global size. + */ +#define THD_WA_SIZE(n) STACK_ALIGN(sizeof(Thread) + \ + sizeof(struct intctx) + \ + sizeof(struct extctx) + \ + (n) + (PORT_INT_REQUIRED_STACK)) + +/** + * @brief Static working area allocation. + * @details This macro is used to allocate a static thread working area + * aligned as both position and size. + */ +#define WORKING_AREA(s, n) stkalign_t s[THD_WA_SIZE(n) / sizeof(stkalign_t)] + +/** + * @brief IRQ prologue code. + * @details This macro must be inserted at the start of all IRQ handlers + * enabled to invoke system APIs. + */ +#define PORT_IRQ_PROLOGUE() + +/** + * @brief IRQ epilogue code. + * @details This macro must be inserted at the end of all IRQ handlers + * enabled to invoke system APIs. + */ +#define PORT_IRQ_EPILOGUE() + +/** + * @brief IRQ handler function declaration. + * @note @p id can be a function name or a vector number depending on the + * port implementation. + */ +#define PORT_IRQ_HANDLER(id) void id(void) + +/** + * @details Implemented as global interrupt disable. + */ +#define port_lock() asm volatile ("wrteei 0" : : : "memory") + +/** + * @details Implemented as global interrupt enable. + */ +#define port_unlock() asm volatile("wrteei 1" : : : "memory") + +/** + * @details Implemented as global interrupt disable. + */ +#define port_lock_from_isr() /*asm ("wrteei 0")*/ + +/** + * @details Implemented as global interrupt enable. + */ +#define port_unlock_from_isr() /*asm ("wrteei 1")*/ + +/** + * @details Implemented as global interrupt disable. + */ +#define port_disable() asm volatile ("wrteei 0" : : : "memory") + +/** + * @details Same as @p port_disable() in this port, there is no difference + * between the two states. + */ +#define port_suspend() asm volatile ("wrteei 0" : : : "memory") + +/** + * @details Implemented as global interrupt enable. + */ +#define port_enable() asm volatile ("wrteei 1" : : : "memory") + +/** + * @brief Performs a context switch between two threads. + * @details This is the most critical code in any port, this function + * is responsible for the context switch between 2 threads. + * @note The implementation of this code affects directly the context + * switch performance so optimize here as much as you can. + * + * @param[in] ntp the thread to be switched in + * @param[in] otp the thread to be switched out + */ +#if !CH_DBG_ENABLE_STACK_CHECK || defined(__DOXYGEN__) +#define port_switch(ntp, otp) _port_switch(ntp, otp) +#else +#define port_switch(ntp, otp) { \ + register struct intctx *sp asm ("%r1"); \ + if ((stkalign_t *)(sp - 1) < otp->p_stklimit) \ + chDbgPanic("stack overflow"); \ + _port_switch(ntp, otp); \ +} +#endif + +/** + * @brief Writes to a special register. + * + * @param[in] spr special register number + * @param[in] val value to be written + */ +#define port_mtspr(spr, val) \ + asm volatile ("mtspr %0,%1" : : "n" (spr), "r" (val)) + +/** + * @details This port function is implemented as inlined code for performance + * reasons. + */ +#if PPC_ENABLE_WFI_IDLE +#if !defined(port_wait_for_interrupt) +#define port_wait_for_interrupt() { \ + asm volatile ("wait" : : : "memory"); \ +} +#endif +#else +#define port_wait_for_interrupt() +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void port_init(void); + void port_halt(void); + void _port_switch(Thread *ntp, Thread *otp); + void _port_thread_start(void); +#ifdef __cplusplus +} +#endif + +#endif /* _FROM_ASM_ */ + +#endif /* _CHCORE_H_ */ + +/** @} */ diff --git a/os/rt/ports/e200/compilers/GCC/chtypes.h b/os/rt/ports/e200/compilers/GCC/chtypes.h new file mode 100644 index 000000000..6eaf26ee5 --- /dev/null +++ b/os/rt/ports/e200/compilers/GCC/chtypes.h @@ -0,0 +1,106 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011,2012,2013 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file PPC/chtypes.h + * @brief PowerPC architecture port system types. + * + * @addtogroup PPC_CORE + * @{ + */ + +#ifndef _CHTYPES_H_ +#define _CHTYPES_H_ + +#include +#include +#include + +/** + * @name Common constants + */ +/** + * @brief Generic 'false' boolean constant. + */ +#if !defined(FALSE) || defined(__DOXYGEN__) +#define FALSE 0 +#endif + +/** + * @brief Generic 'true' boolean constant. + */ +#if !defined(TRUE) || defined(__DOXYGEN__) +#define TRUE (!FALSE) +#endif +/** @} */ + +/** + * @name Derived generic types + * @{ + */ +typedef volatile int8_t vint8_t; /**< Volatile signed 8 bits. */ +typedef volatile uint8_t vuint8_t; /**< Volatile unsigned 8 bits. */ +typedef volatile int16_t vint16_t; /**< Volatile signed 16 bits. */ +typedef volatile uint16_t vuint16_t; /**< Volatile unsigned 16 bits. */ +typedef volatile int32_t vint32_t; /**< Volatile signed 32 bits. */ +typedef volatile uint32_t vuint32_t; /**< Volatile unsigned 32 bits. */ +/** @} */ + +/** + * @name Kernel types + * @{ + */ +typedef uint32_t rtcnt_t; /**< Realtime counter. */ +typedef uint64_t rttime_t; /**< Realtime accumulator. */ +typedef uint32_t syssts_t; /**< System status word. */ +typedef uint8_t tmode_t; /**< Thread flags. */ +typedef uint8_t tstate_t; /**< Thread state. */ +typedef uint8_t trefs_t; /**< Thread references counter. */ +typedef uint8_t tslices_t; /**< Thread time slices counter.*/ +typedef uint32_t tprio_t; /**< Thread priority. */ +typedef int32_t msg_t; /**< Inter-thread message. */ +typedef int32_t eventid_t; /**< Numeric event identifier. */ +typedef uint32_t eventmask_t; /**< Mask of event identifiers. */ +typedef uint32_t eventflags_t; /**< Mask of event flags. */ +typedef int32_t cnt_t; /**< Generic signed counter. */ +typedef uint32_t ucnt_t; /**< Generic unsigned counter. */ +/** @} */ + +/** + * @brief ROM constant modifier. + * @note It is set to use the "const" keyword in this port. + */ +#define ROMCONST const + +/** + * @brief Makes functions not inlineable. + * @note If the compiler does not support such attribute then the + * realtime counter precision could be degraded. + */ +#define NOINLINE __attribute__((noinline)) + +/** + * @brief Optimized thread function declaration macro. + */ +#define PORT_THD_FUNCTION(tname, arg) msg_t tname(void *arg) + +#endif /* _CHTYPES_H_ */ + +/** @} */ -- cgit v1.2.3