git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@7039 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
1272fdce1e
commit
6fd6d0670e
|
@ -14,11 +14,9 @@
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
#include "test.h"
|
||||
#include "shell.h"
|
||||
#include "chprintf.h"
|
||||
#include "nil.h"
|
||||
//#include "hal.h"
|
||||
//#include "test.h"
|
||||
|
||||
#if 0
|
||||
#define SHELL_WA_SIZE THD_WORKING_AREA_SIZE(1024)
|
||||
|
@ -92,7 +90,7 @@ static const ShellConfig shell_cfg1 = {
|
|||
* LEDs blinker thread, times are in milliseconds.
|
||||
*/
|
||||
static THD_WORKING_AREA(waThread1, 128);
|
||||
static msg_t Thread1(void *arg) {
|
||||
static THD_FUNCTION(Thread1, arg) {
|
||||
|
||||
(void)arg;
|
||||
|
||||
|
@ -179,7 +177,7 @@ int main(void) {
|
|||
* - Kernel initialization, the main() function becomes a thread and the
|
||||
* RTOS is active.
|
||||
*/
|
||||
halInit();
|
||||
// halInit();
|
||||
chSysInit();
|
||||
|
||||
/* This is now the idle thread loop, you may perform here a low priority
|
||||
|
|
|
@ -60,7 +60,7 @@
|
|||
/**
|
||||
* @brief System tick frequency.
|
||||
*/
|
||||
#define NIL_CFG_ST_FREQUENCY 50000
|
||||
#define NIL_CFG_ST_FREQUENCY 1000
|
||||
|
||||
/**
|
||||
* @brief Time delta constant for the tick-less mode.
|
||||
|
@ -70,7 +70,7 @@
|
|||
* The value one is not valid, timeouts are rounded up to
|
||||
* this value.
|
||||
*/
|
||||
#define NIL_CFG_ST_TIMEDELTA 2
|
||||
#define NIL_CFG_ST_TIMEDELTA 0
|
||||
|
||||
/** @} */
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ ifeq ($(USE_LINK_GC),yes)
|
|||
OPT += -ffunction-sections -fdata-sections -fno-common
|
||||
LDOPT := --gc-sections
|
||||
else
|
||||
LDOPT :=
|
||||
LDOPT := --no-gc-sections
|
||||
endif
|
||||
|
||||
# Linker extra options
|
||||
|
|
|
@ -52,4 +52,57 @@
|
|||
/* Module exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @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 <b>directly</b> 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 ("li %r0, 0");
|
||||
asm ("bl chSysHalt"); /* Thread termination on exit. */
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
|
|
@ -38,19 +38,19 @@
|
|||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Macro defining the port architecture.
|
||||
* @brief Macro defining an PPC architecture.
|
||||
*/
|
||||
#define PORT_ARCHITECTURE_XXX
|
||||
#define PORT_ARCHITECTURE_PPC
|
||||
|
||||
/**
|
||||
* @brief Macro defining the specific PPC architecture.
|
||||
*/
|
||||
#define PORT_ARCHITECTURE_PPC_E200
|
||||
|
||||
/**
|
||||
* @brief Name of the implemented architecture.
|
||||
*/
|
||||
#define PORT_ARCHITECTURE_NAME "XXX"
|
||||
|
||||
/**
|
||||
* @brief Name of the architecture variant.
|
||||
*/
|
||||
#define PORT_CORE_VARIANT_NAME "XXXX-Y"
|
||||
#define PORT_ARCHITECTURE_NAME "Power Architecture"
|
||||
|
||||
/**
|
||||
* @brief Compiler name and version.
|
||||
|
@ -62,31 +62,30 @@
|
|||
#error "unsupported compiler"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Port-specific information string.
|
||||
*/
|
||||
#define PORT_INFO "port description"
|
||||
|
||||
/**
|
||||
* @brief This port supports a realtime counter.
|
||||
*/
|
||||
#define PORT_SUPPORTS_RT FALSE
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name E200 core variants
|
||||
* @{
|
||||
*/
|
||||
#define PPC_VARIANT_e200z0 200
|
||||
#define PPC_VARIANT_e200z2 202
|
||||
#define PPC_VARIANT_e200z3 203
|
||||
#define PPC_VARIANT_e200z4 204
|
||||
/** @} */
|
||||
|
||||
/* Inclusion of the PPC implementation specific parameters.*/
|
||||
#include "ppcparams.h"
|
||||
#include "vectors.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*/
|
||||
#if !defined(PORT_IDLE_THREAD_STACK_SIZE) || defined(__DOXYGEN__)
|
||||
#define PORT_IDLE_THREAD_STACK_SIZE 16
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Per-thread stack overhead for interrupts servicing.
|
||||
* @details This constant is used in the calculation of the correct working
|
||||
|
@ -110,6 +109,38 @@
|
|||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#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
|
||||
|
||||
/**
|
||||
* @brief Name of the architecture variant.
|
||||
*/
|
||||
#if (PPC_VARIANT == PPC_VARIANT_e200z0) || defined(__DOXYGEN__)
|
||||
#define PORT_CORE_VARIANT_NAME "e200z0"
|
||||
#elif PPC_VARIANT == PPC_VARIANT_e200z2
|
||||
#define PORT_CORE_VARIANT_NAME "e200z2"
|
||||
#elif PPC_VARIANT == PPC_VARIANT_e200z3
|
||||
#define PORT_CORE_VARIANT_NAME "e200z3"
|
||||
#elif PPC_VARIANT == PPC_VARIANT_e200z4
|
||||
#define PORT_CORE_VARIANT_NAME "e200z4"
|
||||
#else
|
||||
#error "unknown or unsupported PowerPC variant specified"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Port-specific information string.
|
||||
*/
|
||||
#if PPC_USE_VLE
|
||||
#define PORT_INFO "VLE mode"
|
||||
#else
|
||||
#define PORT_INFO "Book-E mode"
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
@ -132,22 +163,81 @@ typedef uint16_t systime_t;
|
|||
*/
|
||||
typedef uint64_t stkalign_t;
|
||||
|
||||
/**
|
||||
* @brief Generic PPC register.
|
||||
*/
|
||||
typedef void *regppc_t;
|
||||
|
||||
/**
|
||||
* @brief Mandatory part of a stack frame.
|
||||
*/
|
||||
struct port_eabi_frame {
|
||||
uint32_t slink; /**< Stack back link. */
|
||||
uint32_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 port_extctx {
|
||||
|
||||
};
|
||||
struct port_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 port_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;
|
||||
};
|
||||
|
||||
#endif /* !defined(_FROM_ASM_) */
|
||||
|
@ -162,6 +252,13 @@ struct port_intctx {
|
|||
* by an @p port_intctx structure.
|
||||
*/
|
||||
#define PORT_SETUP_CONTEXT(tp, wend, pf, arg) { \
|
||||
uint8_t *sp = (uint8_t *)(wend) - \
|
||||
sizeof(struct port_eabi_frame); \
|
||||
((struct port_eabi_frame *)sp)->slink = 0; \
|
||||
((struct port_eabi_frame *)sp)->shole = (uint32_t)_port_thread_start; \
|
||||
(tp)->ctxp = (struct port_intctx *)(sp - sizeof(struct port_intctx)); \
|
||||
(tp)->ctxp->r31 = (regppc_t)(arg); \
|
||||
(tp)->ctxp->r30 = (regppc_t)(pf); \
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -184,7 +281,7 @@ struct port_intctx {
|
|||
* @details This macro must be inserted at the end of all IRQ handlers
|
||||
* enabled to invoke system APIs.
|
||||
*/
|
||||
#define PORT_IRQ_EPILOGUE() _port_irq_epilogue()
|
||||
#define PORT_IRQ_EPILOGUE()
|
||||
|
||||
/**
|
||||
* @brief IRQ handler function declaration.
|
||||
|
@ -210,7 +307,34 @@ struct port_intctx {
|
|||
* @param[in] ntp the thread to be switched in
|
||||
* @param[in] otp the thread to be switched out
|
||||
*/
|
||||
#if !NIL_CFG_ENABLE_STACK_CHECK || defined(__DOXYGEN__)
|
||||
#define port_switch(ntp, otp) _port_switch(ntp, otp)
|
||||
#else
|
||||
#define port_switch(ntp, otp) { \
|
||||
register struct port_intctx *sp asm ("%r1"); \
|
||||
if ((stkalign_t *)(sp - 1) < otp->stklim) \
|
||||
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, must be an automatic variable
|
||||
*/
|
||||
#define port_write_spr(spr, val) \
|
||||
asm volatile ("mtspr %[p0], %[p1]" : : [p0] "n" (spr), [p1] "r" (val))
|
||||
|
||||
/**
|
||||
* @brief Writes to a special register.
|
||||
*
|
||||
* @param[in] spr special register number
|
||||
* @param[in] val returned value, must be an automatic variable
|
||||
*/
|
||||
#define port_read_spr(spr, val) \
|
||||
asm volatile ("mfspr %[p0], %[p1]" : [p0] "=r" (val) : [p1] "n" (spr))
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
|
@ -223,7 +347,6 @@ struct port_intctx {
|
|||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void _port_irq_epilogue(void);
|
||||
void _port_switch(thread_t *ntp, thread_t *otp);
|
||||
void _port_thread_start(void);
|
||||
#ifdef __cplusplus
|
||||
|
@ -244,7 +367,24 @@ extern "C" {
|
|||
* @brief Port-related initialization code.
|
||||
*/
|
||||
static inline void port_init(void) {
|
||||
uint32_t n;
|
||||
|
||||
/* Initializing the SPRG0 register to zero, it is required for interrupts
|
||||
handling.*/
|
||||
n = 0;
|
||||
port_write_spr(272, n);
|
||||
|
||||
#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" : : : "r3", "memory");
|
||||
#endif
|
||||
|
||||
/* Interrupt controller initialization.*/
|
||||
intc_init();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -253,8 +393,10 @@ static inline void port_init(void) {
|
|||
* @return The interrupts status.
|
||||
*/
|
||||
static inline syssts_t port_get_irq_status(void) {
|
||||
uint32_t sts;
|
||||
|
||||
return 0;
|
||||
asm volatile ("mfmsr %[p0]" : [p0] "=r" (sts) :);
|
||||
return sts;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -268,7 +410,7 @@ static inline syssts_t port_get_irq_status(void) {
|
|||
*/
|
||||
static inline bool port_irq_enabled(syssts_t sts) {
|
||||
|
||||
return false;
|
||||
return (bool)((sts & (1 << 15)) != 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -279,8 +421,12 @@ static inline bool port_irq_enabled(syssts_t sts) {
|
|||
* @retval true running in ISR mode.
|
||||
*/
|
||||
static inline bool port_is_isr_context(void) {
|
||||
uint32_t sprg0;
|
||||
|
||||
return false;
|
||||
/* The SPRG0 register is increased before entering interrupt handlers and
|
||||
decreased at the end.*/
|
||||
port_read_spr(272, sprg0);
|
||||
return (bool)(sprg0 > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -288,6 +434,7 @@ static inline bool port_is_isr_context(void) {
|
|||
*/
|
||||
static inline void port_lock(void) {
|
||||
|
||||
asm volatile ("wrteei 0" : : : "memory");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -295,6 +442,7 @@ static inline void port_lock(void) {
|
|||
*/
|
||||
static inline void port_unlock(void) {
|
||||
|
||||
asm volatile("wrteei 1" : : : "memory");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -316,6 +464,7 @@ static inline void port_unlock_from_isr(void) {
|
|||
*/
|
||||
static inline void port_disable(void) {
|
||||
|
||||
asm volatile ("wrteei 0" : : : "memory");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -323,6 +472,7 @@ static inline void port_disable(void) {
|
|||
*/
|
||||
static inline void port_suspend(void) {
|
||||
|
||||
asm volatile ("wrteei 0" : : : "memory");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -330,6 +480,7 @@ static inline void port_suspend(void) {
|
|||
*/
|
||||
static inline void port_enable(void) {
|
||||
|
||||
asm volatile ("wrteei 1" : : : "memory");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -341,6 +492,9 @@ static inline void port_enable(void) {
|
|||
*/
|
||||
static inline void port_wait_for_interrupt(void) {
|
||||
|
||||
#if PPC_ENABLE_WFI_IDLE
|
||||
asm volatile ("wait" : : : "memory");
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -77,16 +77,6 @@
|
|||
/* Module pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*/
|
||||
#if !defined(PORT_IDLE_THREAD_STACK_SIZE) || defined(__DOXYGEN__)
|
||||
#define PORT_IDLE_THREAD_STACK_SIZE 16
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Per-thread stack overhead for interrupts servicing.
|
||||
* @details This constant is used in the calculation of the correct working
|
||||
|
|
|
@ -61,6 +61,11 @@
|
|||
#else
|
||||
#error "unsupported compiler"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief This port supports a realtime counter.
|
||||
*/
|
||||
#define PORT_SUPPORTS_RT FALSE
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
|
@ -105,6 +110,16 @@
|
|||
#define PORT_INT_REQUIRED_STACK 256
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables an alternative timer implementation.
|
||||
* @details Usually the port uses a timer interface defined in the file
|
||||
* @p nilcore_timer.h, if this option is enabled then the file
|
||||
* @p nilcore_timer_alt.h is included instead.
|
||||
*/
|
||||
#if !defined(PORT_USE_ALT_TIMER)
|
||||
#define PORT_USE_ALT_TIMER FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Use VLE instruction set.
|
||||
* @note This parameter is usually set in the Makefile.
|
||||
|
@ -545,6 +560,22 @@ static inline rtcnt_t port_rt_get_counter_value(void) {
|
|||
|
||||
#endif /* !defined(_FROM_ASM_) */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module late inclusions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if !defined(_FROM_ASM_)
|
||||
|
||||
#if CH_CFG_ST_TIMEDELTA > 0
|
||||
#if !PORT_USE_ALT_TIMER
|
||||
#include "chcore_timer.h"
|
||||
#else /* PORT_USE_ALT_TIMER */
|
||||
#include "chcore_timer_alt.h"
|
||||
#endif /* PORT_USE_ALT_TIMER */
|
||||
#endif /* CH_CFG_ST_TIMEDELTA > 0 */
|
||||
|
||||
#endif /* !defined(_FROM_ASM_) */
|
||||
|
||||
#endif /* _CHCORE_H_ */
|
||||
|
||||
/** @} */
|
||||
|
|
Loading…
Reference in New Issue