[PATCH 1/7] Patches for the OR1k CPU handling and definitions
Jakob Viketoft
jakob.viketoft at aacmicrotec.com
Fri Feb 19 09:06:10 UTC 2016
diff --git a/cpukit/score/cpu/or1k/rtems/score/or1k-utility.h b/cpukit/score/cpu/or1k/rtems/score/or1k-utility.h
index 98bbe41..78f2468 100644
--- a/cpukit/score/cpu/or1k/rtems/score/or1k-utility.h
+++ b/cpukit/score/cpu/or1k/rtems/score/or1k-utility.h
@@ -4,8 +4,12 @@
* @brief OR1K utility
*/
/*
+ * COPYRIGHT (c) 2014-2015 ÅAC Microtec AB <www.aacmicrotec.com>
+ * Karol Gugala <kgugala at antmicro.com>
+ * Jakob Viketoft <jakob.viketoft at aacmicrotec.com>
* COPYRIGHT (c) 2014 Hesham ALMatary <heshamelmatary at gmail.com>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
@@ -26,8 +30,8 @@
#define SPR_GRP7_PERF_CTR (7 << SPR_GRP_SHAMT)
#define SPR_GRP8_PWR_MNG (8 << SPR_GRP_SHAMT)
#define SPR_GRP9_PIC (9 << SPR_GRP_SHAMT)
-#define SPR_GPR10_TICK_TMR (10 << SPR_GRP_SHAMT)
-#define SPR_GPR11_FPU (11 << SPR_GRP_SHAMT)
+#define SPR_GRP10_TICK_TMR (10 << SPR_GRP_SHAMT)
+#define SPR_GRP11_FPU (11 << SPR_GRP_SHAMT)
/* SPR registers definitions */
@@ -196,8 +200,8 @@
#define CPU_OR1K_SPR_PICSR (SPR_GRP9_PIC + 2)
/* Group10: Tick Timer registers */
-#define CPU_OR1K_SPR_TTMR (SPR_GPR10_TICK_TMR + 0)
-#define CPU_OR1K_SPR_TTCR (SPR_GPR10_TICK_TMR + 1)
+#define CPU_OR1K_SPR_TTMR (SPR_GRP10_TICK_TMR + 0)
+#define CPU_OR1K_SPR_TTCR (SPR_GRP10_TICK_TMR + 1)
/* Shift amount macros for bits position in Supervision Register */
#define CPU_OR1K_SPR_SR_SHAMT_SM (0)
@@ -258,6 +262,114 @@
/*Context ID (Fast Context Switching) */
#define CPU_OR1K_SPR_SR_CID (F << CPU_OR1K_SPR_SR_SHAMT_CID)
+/*
+ * Bit definitions for the Version Register
+ *
+ */
+#define CPU_OR1K_SPR_VR_VER 0xff000000 /* Processor version */
+#define CPU_OR1K_SPR_VR_CFG 0x00ff0000 /* Processor configuration */
+#define CPU_OR1K_SPR_VR_RES 0x0000ffc0 /* Reserved */
+#define CPU_OR1K_SPR_VR_REV 0x0000003f /* Processor revision */
+
+#define CPU_OR1K_SPR_VR_VER_OFF 24
+#define CPU_OR1K_SPR_VR_CFG_OFF 16
+#define CPU_OR1K_SPR_VR_REV_OFF 0
+
+/*
+ * Bit definitions for the Unit Present Register
+ *
+ */
+#define CPU_OR1K_SPR_UPR_UP 0x00000001 /* UPR present */
+#define CPU_OR1K_SPR_UPR_DCP 0x00000002 /* Data cache present */
+#define CPU_OR1K_SPR_UPR_ICP 0x00000004 /* Instruction cache present */
+#define CPU_OR1K_SPR_UPR_DMP 0x00000008 /* Data MMU present */
+#define CPU_OR1K_SPR_UPR_IMP 0x00000010 /* Instruction MMU present */
+#define CPU_OR1K_SPR_UPR_MP 0x00000020 /* MAC present */
+#define CPU_OR1K_SPR_UPR_DUP 0x00000040 /* Debug unit present */
+#define CPU_OR1K_SPR_UPR_PCUP 0x00000080 /* Performance counters unit present */
+#define CPU_OR1K_SPR_UPR_PMP 0x00000100 /* Power management present */
+#define CPU_OR1K_SPR_UPR_PICP 0x00000200 /* PIC present */
+#define CPU_OR1K_SPR_UPR_TTP 0x00000400 /* Tick timer present */
+#define CPU_OR1K_SPR_UPR_RES 0x00fe0000 /* Reserved */
+#define CPU_OR1K_SPR_UPR_CUP 0xff000000 /* Context units present */
+
+/*
+ * Bit definitions for the CPU configuration register
+ *
+ */
+#define CPU_OR1K_SPR_CPUCFGR_NSGF 0x0000000f /* Number of shadow GPR files */
+#define CPU_OR1K_SPR_CPUCFGR_CGF 0x00000010 /* Custom GPR file */
+#define CPU_OR1K_SPR_CPUCFGR_OB32S 0x00000020 /* ORBIS32 supported */
+#define CPU_OR1K_SPR_CPUCFGR_OB64S 0x00000040 /* ORBIS64 supported */
+#define CPU_OR1K_SPR_CPUCFGR_OF32S 0x00000080 /* ORFPX32 supported */
+#define CPU_OR1K_SPR_CPUCFGR_OF64S 0x00000100 /* ORFPX64 supported */
+#define CPU_OR1K_SPR_CPUCFGR_OV64S 0x00000200 /* ORVDX64 supported */
+#define CPU_OR1K_SPR_CPUCFGR_RES 0xfffffc00 /* Reserved */
+
+/*
+ * Bit definitions for the Debug configuration register and other
+ * constants.
+ *
+ */
+#define CPU_OR1K_SPR_DCFGR_NDP 0x00000007 /* Number of matchpoints mask */
+#define CPU_OR1K_SPR_DCFGR_NDP1 0x00000000 /* One matchpoint supported */
+#define CPU_OR1K_SPR_DCFGR_NDP2 0x00000001 /* Two matchpoints supported */
+#define CPU_OR1K_SPR_DCFGR_NDP3 0x00000002 /* Three matchpoints supported */
+#define CPU_OR1K_SPR_DCFGR_NDP4 0x00000003 /* Four matchpoints supported */
+#define CPU_OR1K_SPR_DCFGR_NDP5 0x00000004 /* Five matchpoints supported */
+#define CPU_OR1K_SPR_DCFGR_NDP6 0x00000005 /* Six matchpoints supported */
+#define CPU_OR1K_SPR_DCFGR_NDP7 0x00000006 /* Seven matchpoints supported */
+#define CPU_OR1K_SPR_DCFGR_NDP8 0x00000007 /* Eight matchpoints supported */
+#define CPU_OR1K_SPR_DCFGR_WPCI 0x00000008 /* Watchpoint counters implemented */
+
+/*
+ * Bit definitions for Data Cache Control register
+ *
+ */
+#define CPU_OR1K_SPR_DCCR_EW 0x000000ff /* Enable ways */
+
+/*
+ * Bit definitions for Insn Cache Control register
+ *
+ */
+#define CPU_OR1K_SPR_ICCR_EW 0x000000ff /* Enable ways */
+
+/*
+ * Bit definitions for Data Cache Configuration Register
+ *
+ */
+
+#define CPU_OR1K_SPR_DCCFGR_NCW 0x00000007
+#define CPU_OR1K_SPR_DCCFGR_NCS 0x00000078
+#define CPU_OR1K_SPR_DCCFGR_CBS 0x00000080
+#define CPU_OR1K_SPR_DCCFGR_CWS 0x00000100
+#define CPU_OR1K_SPR_DCCFGR_CCRI 0x00000200
+#define CPU_OR1K_SPR_DCCFGR_CBIRI 0x00000400
+#define CPU_OR1K_SPR_DCCFGR_CBPRI 0x00000800
+#define CPU_OR1K_SPR_DCCFGR_CBLRI 0x00001000
+#define CPU_OR1K_SPR_DCCFGR_CBFRI 0x00002000
+#define CPU_OR1K_SPR_DCCFGR_CBWBRI 0x00004000
+
+#define CPU_OR1K_SPR_DCCFGR_NCW_OFF 0
+#define CPU_OR1K_SPR_DCCFGR_NCS_OFF 3
+#define CPU_OR1K_SPR_DCCFGR_CBS_OFF 7
+
+/*
+ * Bit definitions for Instruction Cache Configuration Register
+ *
+ */
+#define CPU_OR1K_SPR_ICCFGR_NCW 0x00000007
+#define CPU_OR1K_SPR_ICCFGR_NCS 0x00000078
+#define CPU_OR1K_SPR_ICCFGR_CBS 0x00000080
+#define CPU_OR1K_SPR_ICCFGR_CCRI 0x00000200
+#define CPU_OR1K_SPR_ICCFGR_CBIRI 0x00000400
+#define CPU_OR1K_SPR_ICCFGR_CBPRI 0x00000800
+#define CPU_OR1K_SPR_ICCFGR_CBLRI 0x00001000
+
+#define CPU_OR1K_SPR_ICCFGR_NCW_OFF 0
+#define CPU_OR1K_SPR_ICCFGR_NCS_OFF 3
+#define CPU_OR1K_SPR_ICCFGR_CBS_OFF 7
+
/* Tick timer configuration bits */
#define CPU_OR1K_SPR_TTMR_SHAMT_IP 28
#define CPU_OR1K_SPR_TTMR_SHAMT_IE 29
@@ -285,6 +397,84 @@
#define CPU_OR1K_SPR_PMR_DCGE (1 << CPU_OR1K_SPR_PMR_SHAMT_DCGE)
#define CPU_OR1K_SPR_PMR_SUME (1 << CPU_OR1K_SPR_PMR_SHAMT_SUME)
+#define REDZONE_SIZE (128)
+#define EX_FRAME_SIZE (140)
+
+/* Define the different offsets in a Control Context struct for a more
+ * controlled assembler manipulation */
+#define OR1K_CC_GPR1 (0)
+#define OR1K_CC_GPR2 (4)
+#define OR1K_CC_GPR3 (8)
+#define OR1K_CC_GPR4 (12)
+#define OR1K_CC_GPR5 (16)
+#define OR1K_CC_GPR6 (20)
+#define OR1K_CC_GPR7 (24)
+#define OR1K_CC_GPR8 (28)
+#define OR1K_CC_GPR9 (32)
+#define OR1K_CC_GPR10 (36)
+#define OR1K_CC_GPR11 (40)
+#define OR1K_CC_GPR12 (44)
+#define OR1K_CC_GPR13 (48)
+#define OR1K_CC_GPR14 (52)
+#define OR1K_CC_GPR15 (56)
+#define OR1K_CC_GPR16 (60)
+#define OR1K_CC_GPR17 (64)
+#define OR1K_CC_GPR18 (68)
+#define OR1K_CC_GPR19 (72)
+#define OR1K_CC_GPR20 (76)
+#define OR1K_CC_GPR21 (80)
+#define OR1K_CC_GPR22 (84)
+#define OR1K_CC_GPR23 (88)
+#define OR1K_CC_GPR24 (92)
+#define OR1K_CC_GPR25 (96)
+#define OR1K_CC_GPR26 (100)
+#define OR1K_CC_GPR27 (104)
+#define OR1K_CC_GPR28 (108)
+#define OR1K_CC_GPR29 (112)
+#define OR1K_CC_GPR30 (116)
+#define OR1K_CC_GPR31 (120)
+#define OR1K_CC_SR (124)
+#define OR1K_CC_EPCR0 (128)
+#define OR1K_CC_EEAR0 (132)
+#define OR1K_CC_ESR0 (136)
+
+/* Define the different offsets in an ExceptionContext struct for a more
+ * controlled assembler manipulation */
+#define OR1K_EC_GPR1 (4)
+#define OR1K_EC_GPR2 (8)
+#define OR1K_EC_GPR3 (12)
+#define OR1K_EC_GPR4 (16)
+#define OR1K_EC_GPR5 (20)
+#define OR1K_EC_GPR6 (24)
+#define OR1K_EC_GPR7 (28)
+#define OR1K_EC_GPR8 (32)
+#define OR1K_EC_GPR9 (36)
+#define OR1K_EC_GPR10 (40)
+#define OR1K_EC_GPR11 (44)
+#define OR1K_EC_GPR12 (48)
+#define OR1K_EC_GPR13 (52)
+#define OR1K_EC_GPR14 (56)
+#define OR1K_EC_GPR15 (60)
+#define OR1K_EC_GPR16 (64)
+#define OR1K_EC_GPR17 (68)
+#define OR1K_EC_GPR18 (72)
+#define OR1K_EC_GPR19 (76)
+#define OR1K_EC_GPR20 (80)
+#define OR1K_EC_GPR21 (84)
+#define OR1K_EC_GPR22 (88)
+#define OR1K_EC_GPR23 (92)
+#define OR1K_EC_GPR24 (96)
+#define OR1K_EC_GPR25 (100)
+#define OR1K_EC_GPR26 (104)
+#define OR1K_EC_GPR27 (108)
+#define OR1K_EC_GPR28 (112)
+#define OR1K_EC_GPR29 (116)
+#define OR1K_EC_GPR30 (120)
+#define OR1K_EC_GPR31 (124)
+#define OR1K_EC_EPCR0 (128)
+#define OR1K_EC_EEAR0 (132)
+#define OR1K_EC_ESR0 (136)
+
#ifndef ASM
#include <stddef.h>
@@ -301,24 +491,24 @@ extern "C" {
* @see OpenRISC architecture manual - revision 0.
*/
typedef enum {
- OR1K_EXCEPTION_RESET = 1,
- OR1K_EXCEPTION_BUS_ERR = 2,
- OR1K_EXCEPTION_D_PF = 3, /* Data Page Fault */
- OR1K_EXCEPTION_I_PF = 4, /* Instruction Page Fault */
- OR1K_EXCEPTION_TICK_TIMER = 5,
- OR1K_EXCEPTION_ALIGNMENT = 6,
- OR1K_EXCEPTION_I_UNDEF= 7, /* Undefiend instruction */
- OR1K_EXCEPTION_IRQ = 8, /* External interrupt */
- OR1K_EXCPETION_D_TLB = 9, /* Data TLB miss */
- OR1K_EXCPETION_I_TLB = 10, /* Instruction TLB miss */
- OR1K_EXCPETION_RANGE = 11, /* Range exception */
- OR1K_EXCPETION_SYS_CALL = 12,
- OR1K_EXCPETION_FP = 13, /* Floating point exception */
- OR1K_EXCPETION_TRAP = 14, /* Caused by l.trap instruction or by debug unit */
- OR1K_EXCPETION_RESERVED1 = 15,
- OR1K_EXCPETION_RESERVED2 = 16,
- OR1K_EXCPETION_RESERVED3 = 17,
- MAX_EXCEPTIONS = 17,
+ OR1K_EXCEPTION_RESET = 1,
+ OR1K_EXCEPTION_BUS_ERR = 2,
+ OR1K_EXCEPTION_D_PF = 3, /* Data Page Fault */
+ OR1K_EXCEPTION_I_PF = 4, /* Instruction Page Fault */
+ OR1K_EXCEPTION_TICK_TIMER = 5,
+ OR1K_EXCEPTION_ALIGNMENT = 6,
+ OR1K_EXCEPTION_I_UNDEF = 7, /* Undefined instruction */
+ OR1K_EXCEPTION_IRQ = 8, /* External interrupt */
+ OR1K_EXCEPTION_D_TLB = 9, /* Data TLB miss */
+ OR1K_EXCEPTION_I_TLB = 10, /* Instruction TLB miss */
+ OR1K_EXCEPTION_RANGE = 11, /* Range exception */
+ OR1K_EXCEPTION_SYS_CALL = 12,
+ OR1K_EXCEPTION_FP = 13, /* Floating point exception */
+ OR1K_EXCEPTION_TRAP = 14, /* Caused by l.trap instruction or by debug unit */
+ OR1K_EXCEPTION_RESERVED1 = 15,
+ OR1K_EXCEPTION_RESERVED2 = 16,
+ OR1K_EXCEPTION_RESERVED3 = 17,
+ MAX_EXCEPTIONS = 17,
OR1K_EXCEPTION_MAKE_ENUM_32_BIT = 0xffffffff
} OR1K_Symbolic_exception_name;
@@ -385,6 +575,17 @@ static inline void _OR1K_Sync_pipeline( void )
#define _OR1KSIM_CPU_Halt() \
asm volatile ("l.nop 0xc")
+static inline uint32_t _OR1K_Find_First_One(uint32_t value)
+{
+ uint32_t position;
+
+ asm volatile(
+ "l.ff1 %0, %1;\n\t"
+ : "=r" (position) : "r" (value));
+
+ return position;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/cpukit/score/cpu/or1k/cpu.c b/cpukit/score/cpu/or1k/cpu.c
index 3cf6f6b..c52c48b 100644
--- a/cpukit/score/cpu/or1k/cpu.c
+++ b/cpukit/score/cpu/or1k/cpu.c
@@ -34,26 +34,20 @@ void _CPU_Initialize(void)
* @brief Sets the hardware interrupt level by the level value.
*
* @param[in] level for or1k can only range over two values:
- * 0 (enable interrupts) and 1 (disable interrupts). In future
- * implementations if fast context switch is implemented, the level
- * can range from 0 to 15. @see OpenRISC architecture manual.
- *
+ * 0 (enable interrupts) and 1 (disable interrupts).
*/
void _CPU_ISR_Set_level(uint32_t level)
{
uint32_t sr = 0;
- level = (level > 0)? 1 : 0;
-
- /* map level bit to or1k interrupt enable/disable bit in sr register */
- level <<= CPU_OR1K_SPR_SR_SHAMT_IEE;
sr = _OR1K_mfspr(CPU_OR1K_SPR_SR);
- if (level == 0){ /* Enable all interrupts */
+ if (level > 0) {
+ /* Interrupts disable */
+ sr &= ~(CPU_OR1K_SPR_SR_IEE | CPU_OR1K_SPR_SR_TEE);
+ } else {
+ /* Interrupts enable */
sr |= CPU_OR1K_SPR_SR_IEE | CPU_OR1K_SPR_SR_TEE;
-
- } else{
- sr &= ~CPU_OR1K_SPR_SR_IEE;
}
_OR1K_mtspr(CPU_OR1K_SPR_SR, sr);
diff --git a/cpukit/score/cpu/or1k/rtems/score/cpu.h b/cpukit/score/cpu/or1k/rtems/score/cpu.h
index 21cbb6d..8f2b7dc 100644
--- a/cpukit/score/cpu/or1k/rtems/score/cpu.h
+++ b/cpukit/score/cpu/or1k/rtems/score/cpu.h
@@ -6,6 +6,7 @@
* This include file contains macros pertaining to the Opencores
* or1k processor family.
*
+ * COPYRIGHT (c) 2016 ÅAC Microtec AB <www.aacmicrotec.com>
+ * Jakob Viketoft <jakob.viketoft at aacmicrotec.com>
+ * David Hennerström <david.hennerstrom at aacmicrotec.com>
* COPYRIGHT (c) 2014 Hesham ALMatary <heshamelmatary at gmail.com>
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
@@ -18,6 +19,8 @@
* The body has been modified for the Opencores OR1k implementation by
* Chris Ziomkowski. <chris at asics.ws>
*
*/
#ifndef _OR1K_CPU_H
@@ -524,25 +527,14 @@ static inline uint32_t or1k_interrupt_disable( void )
uint32_t sr;
sr = _OR1K_mfspr(CPU_OR1K_SPR_SR);
- _OR1K_mtspr(CPU_OR1K_SPR_SR, (sr & ~CPU_OR1K_SPR_SR_IEE));
-
- return sr;
-}
-
-static inline void or1k_interrupt_enable(uint32_t level)
-{
- uint32_t sr;
-
- /* Enable interrupts and restore rs */
- sr = level | CPU_OR1K_SPR_SR_IEE | CPU_OR1K_SPR_SR_TEE;
- _OR1K_mtspr(CPU_OR1K_SPR_SR, sr);
+ _OR1K_mtspr(CPU_OR1K_SPR_SR, (sr & ~(CPU_OR1K_SPR_SR_TEE | CPU_OR1K_SPR_SR_IEE)));
+ return (sr & CPU_OR1K_SPR_SR_IEE)? 0 : 1;
}
#define _CPU_ISR_Disable( _level ) \
_level = or1k_interrupt_disable()
-
/*
* Enable interrupts to the previous level (returned by _CPU_ISR_Disable).
* This indicates the end of an RTEMS critical section. The parameter
@@ -550,6 +542,20 @@ static inline void or1k_interrupt_enable(uint32_t level)
*
*/
+static inline void or1k_interrupt_enable(uint32_t level)
+{
+ uint32_t sr;
+ sr = _OR1K_mfspr(CPU_OR1K_SPR_SR);
+
+ if (level > 0) {
+ /* Effectively disable interrupts */
+ _OR1K_mtspr(CPU_OR1K_SPR_SR, (sr & ~(CPU_OR1K_SPR_SR_TEE | CPU_OR1K_SPR_SR_IEE)));
+ return;
+ }
+
+ _OR1K_mtspr(CPU_OR1K_SPR_SR, (sr | (CPU_OR1K_SPR_SR_TEE | CPU_OR1K_SPR_SR_IEE)));
+}
+
#define _CPU_ISR_Enable( _level ) \
or1k_interrupt_enable( _level )
@@ -564,7 +570,7 @@ static inline void or1k_interrupt_enable(uint32_t level)
#define _CPU_ISR_Flash( _level ) \
do{ \
_CPU_ISR_Enable( _level ); \
- _OR1K_mtspr(CPU_OR1K_SPR_SR, (_level & ~CPU_OR1K_SPR_SR_IEE)); \
+ or1k_interrupt_disable(); \
} while(0)
/*
@@ -833,16 +839,9 @@ typedef uint16_t Priority_bit_map_Word;
typedef struct {
uint32_t r[32];
- /* The following registers must be saved if we have
- fast context switch disabled and nested interrupt
- levels are enabled.
- */
-#if !OR1K_FAST_CONTEXT_SWITCH_ENABLED
- uint32_t epcr; /* exception PC register */
- uint32_t eear; /* exception effective address register */
- uint32_t esr; /* exception supervision register */
-#endif
-
+ uint32_t epcr; /* Exception PC register */
+ uint32_t eear; /* Exception effective address register */
+ uint32_t esr; /* Exception supervision register */
} CPU_Exception_frame;
/**
Jakob Viketoft
Senior Engineer in RTL and embedded software
ÅAC Microtec AB
Dag Hammarskjölds väg 48
SE-751 83 Uppsala, Sweden
T: +46 702 80 95 97
http://www.aacmicrotec.com
More information about the devel
mailing list