[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