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 <kgug...@antmicro.com> + * Jakob Viketoft <jakob.viket...@aacmicrotec.com> * COPYRIGHT (c) 2014 Hesham ALMatary <heshamelmat...@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.viket...@aacmicrotec.com> + * David Hennerström <david.hennerst...@aacmicrotec.com> * COPYRIGHT (c) 2014 Hesham ALMatary <heshamelmat...@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. <ch...@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 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel