aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2013-11-20 10:13:46 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2013-11-20 10:13:46 +0000
commit665640ba0afdd833f5a727a0741208d0282f01bb (patch)
treea15ddfa92d8d083c8c299feeed5b12ae4f9e1537
parentcdfd3dd254fbc77b69881a24a3bc5e3ee1a5158e (diff)
downloadChibiOS-665640ba0afdd833f5a727a0741208d0282f01bb.tar.gz
ChibiOS-665640ba0afdd833f5a727a0741208d0282f01bb.tar.bz2
ChibiOS-665640ba0afdd833f5a727a0741208d0282f01bb.zip
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@6500 35acf78f-673a-0410-8e92-d51de3d6d3f4
-rw-r--r--os/common/ports/e200/compilers/GCC/ivor.s25
-rw-r--r--os/rt/ports/e200/chcore.h44
2 files changed, 52 insertions, 17 deletions
diff --git a/os/common/ports/e200/compilers/GCC/ivor.s b/os/common/ports/e200/compilers/GCC/ivor.s
index 2f000c531..6d24c0b30 100644
--- a/os/common/ports/e200/compilers/GCC/ivor.s
+++ b/os/common/ports/e200/compilers/GCC/ivor.s
@@ -58,8 +58,8 @@
.globl _IVOR10
.type _IVOR10, @function
_IVOR10:
- /* Creation of the external stack frame (extctx structure).*/
- stwu %sp, -80(%sp) /* Size of the extctx structure.*/
+ /* Saving the external context (port_extctx structure).*/
+ stwu %sp, -80(%sp)
#if PPC_USE_VLE && PPC_SUPPORTS_VLE_MULTI
e_stmvsrrw 8(%sp) /* Saves PC, MSR. */
e_stmvsprw 16(%sp) /* Saves CR, LR, CTR, XER. */
@@ -90,6 +90,11 @@ _IVOR10:
stw %r12, 72(%sp)
#endif /* !(PPC_USE_VLE && PPC_SUPPORTS_VLE_MULTI) */
+ /* Increasing the SPGR0 register.*/
+ mfspr %r0, 272
+ eaddi %r0, %r0, 1
+ mtspr 272, %r0
+
/* Reset DIE bit in TSR register.*/
lis %r3, 0x0800 /* DIS bit mask. */
mtspr 336, %r3 /* TSR register. */
@@ -122,8 +127,8 @@ _IVOR10:
.globl _IVOR4
.type _IVOR4, @function
_IVOR4:
- /* Creation of the external stack frame (extctx structure).*/
- stwu %sp, -80(%sp) /* Size of the extctx structure.*/
+ /* Saving the external context (port_extctx structure).*/
+ stwu %sp, -80(%sp)
#if PPC_USE_VLE && PPC_SUPPORTS_VLE_MULTI
e_stmvsrrw 8(%sp) /* Saves PC, MSR. */
e_stmvsprw 16(%sp) /* Saves CR, LR, CTR, XER. */
@@ -154,6 +159,11 @@ _IVOR4:
stw %r12, 72(%sp)
#endif /* !(PPC_USE_VLE && PPC_SUPPORTS_VLE_MULTI) */
+ /* Increasing the SPGR0 register.*/
+ mfspr %r0, 272
+ eaddi %r0, %r0, 1
+ mtspr 272, %r0
+
/* Software vector address from the INTC register.*/
lis %r3, INTC_IACKR@h
ori %r3, %r3, INTC_IACKR@l /* IACKR register address. */
@@ -195,6 +205,13 @@ _ivor_exit:
#if CH_DBG_SYSTEM_STATE_CHECK
bl dbg_check_unlock
#endif
+
+ /* Decreasing the SPGR0 register.*/
+ mfspr %r0, 272
+ eaddi %r0, %r0, -1
+ mtspr 272, %r0
+
+ /* Restoring the external context.*/
#if PPC_USE_VLE && PPC_SUPPORTS_VLE_MULTI
e_lmvgprw 32(%sp) /* Restores GPR0, GPR3...GPR12. */
e_lmvsprw 16(%sp) /* Restores CR, LR, CTR, XER. */
diff --git a/os/rt/ports/e200/chcore.h b/os/rt/ports/e200/chcore.h
index 70bddf239..7901ed44d 100644
--- a/os/rt/ports/e200/chcore.h
+++ b/os/rt/ports/e200/chcore.h
@@ -347,10 +347,19 @@ struct context {
* @brief Writes to a special register.
*
* @param[in] spr special register number
- * @param[in] val value to be written
+ * @param[in] val value to be written, must be an automatic variable
*/
-#define port_mtspr(spr, val) \
- asm volatile ("mtspr %0, %1" : : "n" (spr), "r" (val))
+#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. */
@@ -384,14 +393,20 @@ extern "C" {
* @details IVOR4 and IVOR10 initialization.
*/
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" : : : "memory");
+ /* 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
}
@@ -403,7 +418,7 @@ static inline void port_init(void) {
static inline syssts_t port_get_irq_status(void) {
uint32_t sts;
- sts = 0;
+ asm volatile ("mfmsr %[p0]" : [p0] "=r" (sts) :);
return sts;
}
@@ -418,7 +433,7 @@ static inline syssts_t port_get_irq_status(void) {
*/
static inline bool port_irq_enabled(syssts_t sts) {
- return (sts & 1) == 0;
+ return (bool)((sts & (1 << 15)) != 0);
}
/**
@@ -429,9 +444,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 (bool)((__get_IPSR() & 0x1FF) != 0);
- 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);
}
/**