From 098755b36f44cc78e742c15ae66eb95063080d48 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Mon, 5 Aug 2002 19:19:45 +0000 Subject: 2002-08-05 Chris Ziomkowski * asm.h, cpu.c, cpu_asm.c, rtems/score/cpu.h, rtems/score/or32.h, rtems/score/types.h: Merged from OpenCores CVS repository. --- cpukit/score/cpu/or32/ChangeLog | 5 + cpukit/score/cpu/or32/asm.h | 12 +- cpukit/score/cpu/or32/cpu.c | 63 +++-- cpukit/score/cpu/or32/cpu_asm.c | 432 ++++++++++++++++++++++++++++-- cpukit/score/cpu/or32/rtems/asm.h | 12 +- cpukit/score/cpu/or32/rtems/score/cpu.h | 358 ++++++++++--------------- cpukit/score/cpu/or32/rtems/score/or32.h | 34 +-- cpukit/score/cpu/or32/rtems/score/types.h | 29 +- 8 files changed, 648 insertions(+), 297 deletions(-) (limited to 'cpukit') diff --git a/cpukit/score/cpu/or32/ChangeLog b/cpukit/score/cpu/or32/ChangeLog index e58ece9c29..f00e539d68 100644 --- a/cpukit/score/cpu/or32/ChangeLog +++ b/cpukit/score/cpu/or32/ChangeLog @@ -1,3 +1,8 @@ +2002-08-05 Chris Ziomkowski + + * asm.h, cpu.c, cpu_asm.c, rtems/score/cpu.h, rtems/score/or32.h, + rtems/score/types.h: Merged from OpenCores CVS repository. + 2002-07-26 Ralf Corsepius * Makefile.am: Build libscorecpu.a instead of rtems-cpu.rel. diff --git a/cpukit/score/cpu/or32/asm.h b/cpukit/score/cpu/or32/asm.h index d98e2c3f2e..945c98f6c6 100644 --- a/cpukit/score/cpu/or32/asm.h +++ b/cpukit/score/cpu/or32/asm.h @@ -23,8 +23,8 @@ * $Id$ */ -#ifndef __OR32_ASM_h -#define __OR32_ASM_h +#ifndef __OR1K_ASM_h +#define __OR1K_ASM_h /* * Indicate we are in an assembly file and get the basic CPU definitions. @@ -33,8 +33,8 @@ #ifndef ASM #define ASM #endif -#include -#include +#include +#include /* * Recent versions of GNU cpp define variables which indicate the @@ -92,8 +92,8 @@ * They may need to put underscores in front of the symbols. */ -#define PUBLIC(sym) .globl SYM (sym) -#define EXTERN(sym) .globl SYM (sym) +#define PUBLIC(sym) .global SYM (sym) +#define EXTERN(sym) .global SYM (sym) #endif /* end of include file */ diff --git a/cpukit/score/cpu/or32/cpu.c b/cpukit/score/cpu/or32/cpu.c index ca0e499125..8180c7c25d 100644 --- a/cpukit/score/cpu/or32/cpu.c +++ b/cpukit/score/cpu/or32/cpu.c @@ -1,5 +1,5 @@ /* - * XXX CPU Dependent Source + * Opencore Or1k CPU Dependent Source * * * COPYRIGHT (c) 1989-1999. @@ -9,7 +9,9 @@ * found in the file LICENSE in this distribution or at * http://www.OARcorp.com/rtems/license.html. * - * $Id$ + * This file adapted from no_bsp board library of the RTEMS distribution. + * The body has been modified for the Bender Or1k implementation by + * Chris Ziomkowski. */ #include @@ -24,15 +26,12 @@ * cpu_table - CPU table to initialize * thread_dispatch - address of disptaching routine * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ void _CPU_Initialize( rtems_cpu_table *cpu_table, - void (*thread_dispatch) /* ignored on this CPU */ + void (*thread_dispatch) ) { /* @@ -64,27 +63,33 @@ void _CPU_Initialize( * * _CPU_ISR_Get_level * - * OR32 Specific Information: + * or1k Specific Information: * - * XXX document implementation including references if appropriate + * There are only 2 interrupt levels for the or1k architecture. + * Either interrupts are enabled or disabled. They are considered + * enabled if both exceptions are enabled (SR_EXR) and interrupts + * are enabled (SR_EIR). If either of these conditions are not + * met, interrupts are disabled, and a level of 1 is returned. */ - -unsigned32 _CPU_ISR_Get_level( void ) -{ - /* - * This routine returns the current interrupt level. - */ - return 0; +inline unsigned32 _CPU_ISR_Get_level( void ) +{ + register unsigned32 sr; + asm("l.mfspr %0,r0,0x17" : "=r" (sr)); + return !((sr & SR_EXR) && (sr & SR_EIR)); } /*PAGE * * _CPU_ISR_install_raw_handler * - * OR32 Specific Information: + * or1k Specific Information: * - * XXX document implementation including references if appropriate + * As a general rule the following is done for interrupts: + * + * For normal exceptions, exceptions are immediately reenabled + * by setting the SR_EXR bit. For interrupt exceptions, the + * SR_EIR bit is first cleared, and then exceptions are reenabled. */ void _CPU_ISR_install_raw_handler( @@ -93,10 +98,16 @@ void _CPU_ISR_install_raw_handler( proc_ptr *old_handler ) { - /* - * This is where we install the interrupt handler into the "raw" interrupt - * table used by the CPU to dispatch interrupt handlers. - */ + register unsigned32 sr; + register unsigned32 tmp; + extern unsigned32 Or1k_Interrupt_Vectors[]; + + asm volatile ("l.mfspr %0,r0,0x11\n\t" + "l.addi %1,r0,-5\n\t" + "l.and %1,%1,%0\n\t": "=r" (sr) : "r" (tmp)); + *old_handler = *((proc_ptr*)&Or1k_Interrupt_Vectors[vector]); + *((proc_ptr*)&Or1k_Interrupt_Vectors[vector]) = new_handler; + asm volatile ("l.mtspr r0,%0,0x11\n\t":: "r" (sr)); } /*PAGE @@ -114,7 +125,7 @@ void _CPU_ISR_install_raw_handler( * Output parameters: NONE * * - * OR32 Specific Information: + * NO_CPU Specific Information: * * XXX document implementation including references if appropriate */ @@ -146,10 +157,9 @@ void _CPU_ISR_install_vector( /*PAGE * * _CPU_Install_interrupt_stack + * + * We don't use a separate interrupt stack. * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ void _CPU_Install_interrupt_stack( void ) @@ -172,9 +182,6 @@ void _CPU_Install_interrupt_stack( void ) * also be a problem with other on-chip peripherals. So use this * hook with caution. * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ void _CPU_Thread_Idle_body( void ) diff --git a/cpukit/score/cpu/or32/cpu_asm.c b/cpukit/score/cpu/or32/cpu_asm.c index 2e7623fb69..0b149ad7b4 100644 --- a/cpukit/score/cpu/or32/cpu_asm.c +++ b/cpukit/score/cpu/or32/cpu_asm.c @@ -13,7 +13,9 @@ * found in the file LICENSE in this distribution or at * http://www.OARcorp.com/rtems/license.html. * - * $Id$ + * This file adapted from no_bsp board library of the RTEMS distribution. + * The body has been modified for the Bender Or1k implementation by + * Chris Ziomkowski. */ /* @@ -38,15 +40,84 @@ * like a (Context_Control_fp *). The general rule on making this decision * is to avoid writing assembly language. * - * OR32 Specific Information: + * or1k specific Information: * - * XXX document implementation including references if appropriate + * This implementation of RTEMS considers the concept of + * "fast context switching", as defined in the or1k architecture + * specification. Whether or not this makes a significant + * impact on speed is dubious, however it is not a significant + * impediment to include it. It probably wastes a few cycles on + * every floating point context switch. + * + * This implementation will currently not work on a processor where + * the integer unit and floating point unit are not the same size. I + * am waiting on an architecture change to make this feasible. It + * should work fine on 64 bit architectures, except for the fact that + * the variables are declared as 32 bits. This shouldn't really make + * a difference, as the fact that they must be registers should force + * them into a 64 bit word anyway. + * + * The decision as to whether to do 32 or 64 bit saves is performed + * at run time based on the configuration of the CPUCFGR register. This + * takes a performance hit of a few cycles, but this should be a very + * small percentage of the total number of cycles necessary to do the + * save, and doesn't require special code for 32 or 64 bit versions. + * + * ADDITIONAL INFORMATION: + * + * It has been unanimously agreed that floating point will not be + * included in the initial releases of the Or1k chips, and that + * significant changes to the floating point architecture may + * occur before any such release will ever be implemented. The code + * below is therefore never called and never used. */ void _CPU_Context_save_fp( void **fp_context_ptr ) { + register unsigned32 temp; + register unsigned32 address = (unsigned32)(*fp_context_ptr); + register unsigned32 xfer; + register unsigned32 loop; + + /* %0 is a temporary register which is used for several + values throughout the code. %3 contains the address + to save the context, and is modified during the course + of the context save. %1 is a second dummy register + which is used during transfer of the floating point + value to memory. %2 is an end of loop marker which + is compared against the pointer %3. */ + + asm volatile ("l.mfspr %0,r0,0x02 \n\t" /* CPUCFGR */ + "l.andi %0,%0,0x380 \n\t" /* OF32S or OV64S or OF64S */ + "l.sfnei %0,0x0 \n\t" + "l.bf _L_nofps \n\t" /* exit if no floating point */ + "l.sfeqi %0,0x080 \n\t" /* (DELAY) single precision? */ + "l.mfspr %0,r0,0x11 \n\t" /* Load Status Register */ + "l.srli %0,%0,58 \n\t" /* Move CID into low byte*32 */ + "l.bnf _L_spfp_loops \n\t" /* Branch on single precision */ + "l.addi %2,%0,0x20 \n" /* Terminating condition */ + /**** Double Precision Floating Point Section ****/ + "_L_dpfp_loops: \n\t" + "l.mfspr %1,%0,0x600 \n\t" /* Load VFRx */ + "l.sd 0(%3),%1 \n\t" /* Save VFRx */ + "l.addi %0,%0,0x01 \n\t" /* Increment counter */ + "l.sfeq %0,%2 \n\t" /* Branch if incomplete */ + "l.bf _L_dpfp_loops \n\t" + "l.addi %3,%3,0x08 \n\t" /* (DELAY) update pointer */ + "l.bnf _L_nofps \n\t" /* exit */ + "l.nop \n" + /**** Single Precision Floating Point Section ****/ + "_L_spfp_loops: \n\t" + "l.mfspr %1,%0,0x600 \n\t" /* Load VFRx */ + "l.sw 0(%3),%1 \n\t" /* Save VFRx */ + "l.addi %0,%0,0x01 \n\t" /* Increment counter */ + "l.sfeq %0,%2 \n\t" /* Branch if incomplete */ + "l.bf _L_spfp_loops \n\t" + "l.addi %3,%3,0x04 \n" /* (DELAY) update pointer */ + "_L_nofps: \n\t" /* End of context save */ + : "=&r" (temp), "=r" (xfer), "=&r" (loop), "+r" (address)); } /* @@ -56,27 +127,63 @@ void _CPU_Context_save_fp( * at *fp_context_ptr. If the point to load the FP context * from is changed then the pointer is modified by this routine. * - * Sometimes a macro implementation of this is in cpu.h which dereferences - * the ** and a similarly named routine in this file is passed something - * like a (Context_Control_fp *). The general rule on making this decision - * is to avoid writing assembly language. - * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate + * */ void _CPU_Context_restore_fp( void **fp_context_ptr ) { + register unsigned32 temp; + register unsigned32 address = (unsigned32)(*fp_context_ptr); + register unsigned32 xfer; + register unsigned32 loop; + + /* The reverse of Context_save_fp */ + /* %0 is a temporary register which is used for several + values throughout the code. %1 contains the address + to save the context, and is modified during the course + of the context save. %2 is a second dummy register + which is used during transfer of the floating point + value to memory. %3 is an end of loop marker which + is compared against the pointer %1. */ + + asm volatile ("l.mfspr %0,r0,0x02 \n\t" /* CPUCFGR */ + "l.andi %0,%0,0x380 \n\t" /* OF32S or OV64S or OF64S */ + "l.sfnei %0,0x0 \n\t" + "l.bf _L_nofpr \n\t" /* exit if no floating point */ + "l.sfeqi %0,0x080 \n\t" /* (DELAY) single precision? */ + "l.mfspr %0,r0,0x11 \n\t" /* Load Status Register */ + "l.srli %0,%0,58 \n\t" /* Move CID into low byte*32 */ + "l.bnf _L_spfp_loopr \n\t" /* Branch on single precision */ + "l.addi %3,%0,0x20 \n" /* Terminating condition */ + /**** Double Precision Floating Point Section ****/ + "_L_dpfp_loopr: \n\t" + "l.mfspr %2,%0,0x600 \n\t" /* Load VFRx */ + "l.sd 0(%1),%2 \n\t" /* Save VFRx */ + "l.addi %0,%0,0x01 \n\t" /* Increment counter */ + "l.sfeq %0,%3 \n\t" /* Branch if incomplete */ + "l.bf _L_dpfp_loopr \n\t" + "l.addi %1,%1,0x08 \n\t" /* (DELAY) update pointer */ + "l.bnf _L_nofpr \n\t" /* exit */ + "l.nop \n" + /**** Single Precision Floating Point Section ****/ + "_L_spfp_loopr: \n\t" + "l.mfspr %2,%0,0x600 \n\t" /* Load VFRx */ + "l.sw 0(%1),%2 \n\t" /* Save VFRx */ + "l.addi %0,%0,0x01 \n\t" /* Increment counter */ + "l.sfeq %0,%3 \n\t" /* Branch if incomplete */ + "l.bf _L_spfp_loopr \n\t" + "l.addi %1,%1,0x04 \n" /* (DELAY) update pointer */ + "_L_nofpr: \n\t" /* End of context save */ + : "=&r" (temp), "+r" (address), "=r" (xfer), "=&r" (loop)); } /* _CPU_Context_switch * * This routine performs a normal non-FP context switch. * - * OR32 Specific Information: + * NO_CPU Specific Information: * * XXX document implementation including references if appropriate */ @@ -86,6 +193,278 @@ void _CPU_Context_switch( Context_Control *heir ) { + register unsigned32 temp1 = 0; + register unsigned32 temp2 = 0; + + /* This function is really tricky. When this function is called, + we should save our state as we need it, and then grab the + new state from the pointer. We then do a longjump to this + code, replacing the current stack pointer with the new + environment. This function never returns. Instead, at some + later time, another person will call context switch with + our pointer in the heir variable, and they will longjump + to us. We will then continue. Let's see how this works... */ + + /* Technically, we could probably not worry about saving r3 + and r4, since these are parameters guaranteed to be saved + by the calling function. We could also probably get away + without saving r11, as that is filled in by the return + statement. But as a first cut I'm in favor of just saving + everything.... */ + + /* We could be more efficient and use compile time directives + for 32 or 64 bit, but this will allow the code to run on + everything without modification. Feel free to comment the + relevant sections out if you don't need it. */ + + /* We should probably write this whole routine in assembly + so that we can have seperate entry points for self restore + or context switch. You can't jump to local labels from + inline assembly across function calls, and I don't feel + like embedding all the .global directives here...it really + screws up the debugger. Oh well, what's 2 more instructions + and a branch really cost... */ + + /* One thing which we should do is check for 32 or 64 bit models + first, and then do one branch to the appropriate code section. + Currently, we check the architecture bit in CPUCFGR twice. Once + during the load section and again during restore. That is inefficient, + and considering this code is huge anyway, saving the few bytes + simply doesn't make any practical sense. FIX THIS LATER. */ + + /* Note that this routine assumes software context switches are + done with the same CID. In other words, it will not manage + the CIDs and assign a new one as necessary. If you tell it + to restore a context at CID 2, and the current one is at CID + 4, it will do what it is told. It will overwrite the registers + for context ID 2, meaning they are irretrievably lost. I hope + you saved them earlier.... */ + + /* Note that you can have a context jump anywhere you want, although + by default we will jump to the L_restore label. If you then modify + the location in the Context_Control structure, it will continue + whereever you told it to go. Note however that you had better + also have cleaned up the stack and frame pointers though, because + they are probably still set with the values obtained from + entering this function... */ + + asm volatile ("l.sfeqi %3,0x0 \n\t" /* Is this a self restore? */ + "l.bf _L_restore \n\t" /* Yes it is...go there */ + "l.nop \n\t" + + "l.lwz %0,0(%3) \n\t" /* Prefetch new context */ + "l.mfspr %2,r0,0x11 \n\t" /* Status Register */ + "l.sw 0(%1),%2 \n\t" /* Save it */ + "l.srli %2,%2,28 \n\t" /* Move CID into low byte */ + "l.mfspr %0,%2,0x20 \n\t" /* Offset from EPCR */ + "l.sw 4(%1),%0 \n\t" /* Store it */ + "l.mfspr %0,%2,0x30 \n\t" /* Offset from EEAR */ + "l.sw 8(%1),%0 \n\t" /* Store it */ + "l.mfspr %0,%2,0x40 \n\t" /* Offset from ESR */ + "l.sw 12(%1),%0 \n\t" /* Store it */ + "l.mfspr %0,r0,0x02 \n\t" /* CPUCFGR */ + "l.andi %0,%0,0x40 \n\t" /* OB64S */ + "l.sfnei %0,0x0 \n\t" + "l.bf _L_64bit \n\t" /* 64 bit architecture */ + "l.movhi %0,hi(_L_restore)\n\t" + + /**** 32 bit implementation ****/ + "l.ori %0,%0,lo(_L_restore)\n\t" + "l.sw 140(%1),%0 \n\t" /* Save the PC */ + "l.lwz %0,140(%3) \n\t" /* New PC. Expect cache miss */ + "l.sw 16(%1),r1 \n\t" + "l.sw 20(%1),r2 \n\t" + "l.sw 24(%1),r3 \n\t" + "l.sw 28(%1),r4 \n\t" + "l.sw 32(%1),r5 \n\t" + "l.sw 36(%1),r6 \n\t" + "l.sw 40(%1),r7 \n\t" + "l.sw 44(%1),r8 \n\t" + "l.sw 48(%1),r9 \n\t" + "l.sw 52(%1),r10 \n\t" + "l.sw 56(%1),r11 \n\t" + "l.sw 60(%1),r12 \n\t" + "l.sw 64(%1),r13 \n\t" + "l.sw 68(%1),r14 \n\t" + "l.sw 72(%1),r15 \n\t" + "l.sw 76(%1),r16 \n\t" + "l.sw 80(%1),r17 \n\t" + "l.sw 84(%1),r18 \n\t" + "l.sw 88(%1),r19 \n\t" + "l.sw 92(%1),r20 \n\t" + "l.sw 96(%1),r21 \n\t" + "l.sw 100(%1),r22 \n\t" + "l.sw 104(%1),r23 \n\t" + "l.sw 108(%1),r24 \n\t" + "l.sw 112(%1),r25 \n\t" + "l.sw 116(%1),r26 \n\t" + "l.sw 120(%1),r27 \n\t" + "l.sw 124(%1),r28 \n\t" + "l.sw 128(%1),r29 \n\t" + "l.sw 132(%1),r30 \n\t" + "l.jr %0 \n\t" /* Go there */ + "l.sw 136(%1),r31 \n" /* Store the last reg */ + + /**** 64 bit implementation ****/ + "_L_64bit: \n\t" + "l.ori %0,%0,lo(_L_restore)\n\t" + "l.sw 264(%1),%0 \n\t" + "l.sd 16(%1),r1 \n\t" + "l.sd 24(%1),r2 \n\t" + "l.sd 32(%1),r3 \n\t" + "l.sd 40(%1),r4 \n\t" + "l.sd 48(%1),r5 \n\t" + "l.sd 56(%1),r6 \n\t" + "l.sd 64(%1),r7 \n\t" + "l.sd 72(%1),r8 \n\t" + "l.sd 80(%1),r9 \n\t" + "l.sd 88(%1),r10 \n\t" + "l.sd 96(%1),r11 \n\t" + "l.sd 104(%1),r12 \n\t" + "l.sd 112(%1),r13 \n\t" + "l.sd 120(%1),r14 \n\t" + "l.sd 128(%1),r15 \n\t" + "l.sd 136(%1),r16 \n\t" + "l.sd 144(%1),r17 \n\t" + "l.sd 152(%1),r18 \n\t" + "l.sd 160(%1),r19 \n\t" + "l.sd 168(%1),r20 \n\t" + "l.sd 176(%1),r21 \n\t" + "l.sd 184(%1),r22 \n\t" + "l.sd 192(%1),r23 \n\t" + "l.sd 200(%1),r24 \n\t" + "l.sd 208(%1),r25 \n\t" + "l.sd 216(%1),r26 \n\t" + "l.sd 224(%1),r27 \n\t" + "l.sd 232(%1),r28 \n\t" + "l.sd 240(%1),r29 \n\t" + "l.sd 248(%1),r30 \n\t" + "l.jr %0 \n\t" /* Go to the new PC */ + "l.sd 256(%1),r31 \n" /* Store the last reg */ + + /**** The restoration routine. ****/ + + /* Note that when we return from this function, + we will actually be returning to a different + context than when we left. The debugger might + have conniptions over this, but we'll have to + reengineer that later. The stack and status + registers will all be changed, however we + will not touch the global interrupt mask. */ + + /* Also note, when doing any restore, the most + important registers are r1, r2, and r9. These + will be accessed immediately upon exiting the + routine, and so we want to make sure we load + them as early as possible in case they are + not in cache */ + + "_L_restore: \n\t" /* Restore "heir" */ + "l.mfspr %2,r0,0x11 \n\t" /* Status Register */ + "l.movhi %0,0x07FF \n\t" /* ~SR mask */ + "l.ori %0,%0,0xD1FF \n\t" + "l.and %2,%0,%2 \n\t" /* save the global bits */ + "l.movhi %0,0xF800 \n\t" /* SR mask */ + "l.ori %0,%0,0x2E00 \n\t" + "l.lwz %1,0(%3) \n\t" /* Get the previous SR */ + "l.and %0,%1,%0 \n\t" /* Mask out the global bits */ + "l.or %2,%2,%0 \n\t" /* Combine local/global */ + "l.mtspr r0,%2,0x11 \n\t" /* Restore the status register */ + + "l.mfspr %0,r0,0x02 \n\t" /* CPUCFGR */ + "l.andi %0,%0,0x40 \n\t" /* OB64S */ + "l.sfnei %0,0x0 \n\t" /* Save the 64 bit flag */ + + "l.srli %2,%2,28 \n\t" /* Move CID into low byte */ + "l.lwz %0,4(%3) \n\t" + "l.mtspr %2,%0,0x20 \n\t" /* Offset from EPCR */ + "l.lwz %0,8(%3) \n\t" + "l.mtspr %2,%0,0x30 \n\t" /* Offset from EEAR */ + "l.lwz %0,12(%3) \n\t" + + "l.bf _L_r64bit \n\t" /* 64 bit architecture */ + "l.mtspr %2,%0,0x30 \n\t" /* Offset from EEAR (DELAY) */ + + /**** 32 bit restore ****/ + "l.lwz r1,16(%3) \n\t" + "l.lwz r2,20(%3) \n\t" + "l.lwz r9,48(%3) \n\t" + "l.lwz r3,24(%3) \n\t" + "l.lwz r4,28(%3) \n\t" + "l.lwz r5,32(%3) \n\t" + "l.lwz r6,36(%3) \n\t" + "l.lwz r7,40(%3) \n\t" + "l.lwz r8,44(%3) \n\t" + "l.lwz r10,52(%3) \n\t" + "l.lwz r11,56(%3) \n\t" + "l.lwz r12,60(%3) \n\t" + "l.lwz r13,64(%3) \n\t" + "l.lwz r14,68(%3) \n\t" + "l.lwz r15,72(%3) \n\t" + "l.lwz r16,76(%3) \n\t" + "l.lwz r17,80(%3) \n\t" + "l.lwz r18,84(%3) \n\t" + "l.lwz r19,88(%3) \n\t" + "l.lwz r20,92(%3) \n\t" + "l.lwz r21,96(%3) \n\t" + "l.lwz r22,100(%3) \n\t" + "l.lwz r23,104(%3) \n\t" + "l.lwz r24,108(%3) \n\t" + "l.lwz r25,112(%3) \n\t" + "l.lwz r26,116(%3) \n\t" + "l.lwz r27,120(%3) \n\t" + "l.lwz r28,124(%3) \n\t" + "l.lwz r29,128(%3) \n\t" + "l.lwz r30,132(%3) \n\t" + "l.j _L_return \n\t" + "l.lwz r31,136(%3) \n" + + /**** 64 bit restore ****/ + "_L_r64bit: \n\t" + "l.ld r1,16(%3) \n\t" + "l.ld r2,24(%3) \n\t" + "l.ld r9,80(%3) \n\t" + "l.ld r3,32(%3) \n\t" + "l.ld r4,40(%3) \n\t" + "l.ld r5,48(%3) \n\t" + "l.ld r6,56(%3) \n\t" + "l.ld r7,64(%3) \n\t" + "l.ld r8,72(%3) \n\t" + "l.ld r10,88(%3) \n\t" + "l.ld r11,96(%3) \n\t" + "l.ld r12,104(%3) \n\t" + "l.ld r13,112(%3) \n\t" + "l.ld r14,120(%3) \n\t" + "l.ld r15,128(%3) \n\t" + "l.ld r16,136(%3) \n\t" + "l.ld r17,144(%3) \n\t" + "l.ld r18,152(%3) \n\t" + "l.ld r19,160(%3) \n\t" + "l.ld r20,168(%3) \n\t" + "l.ld r21,176(%3) \n\t" + "l.ld r22,184(%3) \n\t" + "l.ld r23,192(%3) \n\t" + "l.ld r24,200(%3) \n\t" + "l.ld r25,208(%3) \n\t" + "l.ld r26,216(%3) \n\t" + "l.ld r27,224(%3) \n\t" + "l.ld r28,232(%3) \n\t" + "l.ld r29,240(%3) \n\t" + "l.ld r30,248(%3) \n\t" + "l.ld r31,256(%3) \n" + + "_L_return: \n\t" /* End of routine */ + + : "=&r" (temp1), "+r" (run), "=&r" (temp2) + : "r" (heir)); + + /* Note that some registers were used for parameter passing and + temporary registeres (temp1 and temp2). These values were + saved and restored across context calls, but the values that + the caller needs should have been stored on the stack. The + C code should now restore these from the stack, since r1 and + r2 have been restored, and return to the location specified + by r9. Then, all should be happy in the world. */ } /* @@ -96,27 +475,31 @@ void _CPU_Context_switch( * * NOTE: May be unnecessary to reload some registers. * - * OR32 Specific Information: + * Or1k Specific Information: * - * XXX document implementation including references if appropriate + * In our implementation, this simply redirects to swich context */ void _CPU_Context_restore( - Context_Control *new_context + Context_Control *run ) { + _CPU_Context_switch(run,NULL); } + /* void __ISR_Handler() * * This routine provides the RTEMS interrupt management. * - * OR32 Specific Information: + * Or1k Specific Information: * - * XXX document implementation including references if appropriate + * Based on the Or1k interrupt architecture described in chapter 16 + * and the exception architecture described in chapter 9 */ -void _ISR_Handler() +void _ISR_Handler(unsigned32 vector,unsigned32 ProgramCounter, + unsigned32 EffectiveAddress,unsigned32 StatusRegister) { /* * This discussion ignores a lot of the ugly details in a real @@ -179,5 +562,18 @@ void _ISR_Handler() * prepare to get out of interrupt * return from interrupt */ + + /* In the Or1k architecture, exceptions are handled in the + startup code of the board support package. Thus, this + routine is never called. Or1k exception routines are called + with the following prototype: + + function(int vector#, int PC, int Address, int StatusRegister); + + These parameters are snapshots of the system when the exception + was encountered. If virtual memory is active, things like the + PC and Address may have little meaning, as they are referenced + in physical space, not the virtual space of the process. + */ } diff --git a/cpukit/score/cpu/or32/rtems/asm.h b/cpukit/score/cpu/or32/rtems/asm.h index d98e2c3f2e..945c98f6c6 100644 --- a/cpukit/score/cpu/or32/rtems/asm.h +++ b/cpukit/score/cpu/or32/rtems/asm.h @@ -23,8 +23,8 @@ * $Id$ */ -#ifndef __OR32_ASM_h -#define __OR32_ASM_h +#ifndef __OR1K_ASM_h +#define __OR1K_ASM_h /* * Indicate we are in an assembly file and get the basic CPU definitions. @@ -33,8 +33,8 @@ #ifndef ASM #define ASM #endif -#include -#include +#include +#include /* * Recent versions of GNU cpp define variables which indicate the @@ -92,8 +92,8 @@ * They may need to put underscores in front of the symbols. */ -#define PUBLIC(sym) .globl SYM (sym) -#define EXTERN(sym) .globl SYM (sym) +#define PUBLIC(sym) .global SYM (sym) +#define EXTERN(sym) .global SYM (sym) #endif /* end of include file */ diff --git a/cpukit/score/cpu/or32/rtems/score/cpu.h b/cpukit/score/cpu/or32/rtems/score/cpu.h index 16efc9d6a2..05894020dd 100644 --- a/cpukit/score/cpu/or32/rtems/score/cpu.h +++ b/cpukit/score/cpu/or32/rtems/score/cpu.h @@ -1,7 +1,7 @@ /* cpu.h * - * This include file contains information pertaining to the XXX - * processor. + * This include file contains macros pertaining to the Opencores + * or1k processor family. * * COPYRIGHT (c) 1989-1999. * On-Line Applications Research Corporation (OAR). @@ -10,19 +10,22 @@ * found in the file LICENSE in this distribution or at * http://www.OARcorp.com/rtems/license.html. * - * $Id$ + * This file adapted from no_cpu example of the RTEMS distribution. + * The body has been modified for the Opencores Or1k implementation by + * Chris Ziomkowski. + * */ -#ifndef __CPU_h -#define __CPU_h +#ifndef _OR1K_CPU_h +#define _OR1K_CPU_h #ifdef __cplusplus extern "C" { #endif -#include /* pick up machine definitions */ +#include "rtems/score/or1k.h" /* pick up machine definitions */ #ifndef ASM -#include +#include "rtems/score/or1ktypes.h" #endif /* conditional compilation parameters */ @@ -43,9 +46,6 @@ extern "C" { * _Thread_Dispatch. If the enable dispatch is inlined, then * one subroutine call is avoided entirely.] * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ #define CPU_INLINE_ENABLE_DISPATCH FALSE @@ -67,9 +67,6 @@ extern "C" { * code is the longest interrupt disable period in RTEMS. So it is * necessary to strike a balance when setting this parameter. * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ #define CPU_UNROLL_ENQUEUE_PRIORITY TRUE @@ -97,9 +94,13 @@ extern "C" { * is unclear what that would imply about the interrupt processing * procedure on that CPU. * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate + * For the first cut of an Or1k implementation, let's not worry + * about this, and assume that our C code will autoperform any + * frame/stack allocation for us when the procedure is entered. + * If we write assembly code, we may have to deal with this manually. + * This can be changed later if we find it is impossible. This + * behavior is desireable as it allows us to work in low memory + * environments where we don't have room for a dedicated stack. */ #define CPU_HAS_SOFTWARE_INTERRUPT_STACK FALSE @@ -118,12 +119,9 @@ extern "C" { * is unclear what that would imply about the interrupt processing * procedure on that CPU. * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ -#define CPU_HAS_HARDWARE_INTERRUPT_STACK TRUE +#define CPU_HAS_HARDWARE_INTERRUPT_STACK FALSE /* * Does RTEMS allocate a dedicated interrupt stack in the Interrupt Manager? @@ -134,21 +132,15 @@ extern "C" { * This should be TRUE is CPU_HAS_SOFTWARE_INTERRUPT_STACK is TRUE * or CPU_INSTALL_HARDWARE_INTERRUPT_STACK is TRUE. * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ -#define CPU_ALLOCATE_INTERRUPT_STACK TRUE +#define CPU_ALLOCATE_INTERRUPT_STACK FALSE /* * Does the RTEMS invoke the user's ISR with the vector number and * a pointer to the saved interrupt frame (1) or just the vector * number (0)? * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ #define CPU_ISR_PASSES_FRAME_POINTER 0 @@ -162,7 +154,7 @@ extern "C" { * If there is a FP coprocessor such as the i387 or mc68881, then * the answer is TRUE. * - * The macro name "OR32_HAS_FPU" should be made CPU specific. + * The macro name "OR1K_HAS_FPU" should be made CPU specific. * It indicates whether or not this CPU model has FP support. For * example, it would be possible to have an i386_nofp CPU model * which set this to false to indicate that you have an i386 without @@ -174,17 +166,22 @@ extern "C" { * is very tool specific and the state saved/restored is also * compiler specific. * - * OR32 Specific Information: + * Or1k Specific Information: * - * XXX document implementation including references if appropriate + * At this time there are no implementations of Or1k that are + * expected to implement floating point. More importantly, the + * floating point architecture is expected to change significantly + * before such chips are fabricated. */ -#if ( OR32_HAS_FPU == 1 ) +#if ( OR1K_HAS_FPU == 1 ) #define CPU_HARDWARE_FP TRUE +#define CPU_SOFTWARE_FP FALSE #else #define CPU_HARDWARE_FP FALSE +#define CPU_SOFTWARE_FP TRUE #endif -#define CPU_SOFTWARE_FP FALSE + /* * Are all tasks RTEMS_FLOATING_POINT tasks implicitly? @@ -201,12 +198,9 @@ extern "C" { * * If CPU_HARDWARE_FP is FALSE, then this should be FALSE as well. * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ -#define CPU_ALL_TASKS_ARE_FP TRUE +#define CPU_ALL_TASKS_ARE_FP FALSE /* * Should the IDLE task have a floating point context? @@ -219,9 +213,6 @@ extern "C" { * the IDLE task from an interrupt because the floating point context * must be saved as part of the preemption. * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ #define CPU_IDLE_TASK_IS_FP FALSE @@ -251,9 +242,6 @@ extern "C" { * Thus in a system with only one FP task, the FP context will never * be saved or restored. * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ #define CPU_USE_DEFERRED_FP_SWITCH TRUE @@ -278,12 +266,9 @@ extern "C" { * 2. CPU dependent (if provided) * 3. generic (if no BSP and no CPU dependent) * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ -#define CPU_PROVIDES_IDLE_THREAD_BODY TRUE +#define CPU_PROVIDES_IDLE_THREAD_BODY FALSE /* * Does the stack grow up (toward higher addresses) or down @@ -292,12 +277,15 @@ extern "C" { * If TRUE, then the grows upward. * If FALSE, then the grows toward smaller addresses. * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate + * Or1k Specific Information: + * + * Previously I had misread the documentation and set this + * to true. Surprisingly, it seemed to work anyway. I'm + * therefore not 100% sure exactly what this does. It should + * be correct as it is now, however. */ -#define CPU_STACK_GROWS_UP TRUE +#define CPU_STACK_GROWS_UP FALSE /* * The following is the variable attribute used to force alignment @@ -318,20 +306,21 @@ extern "C" { * used so it will stay in the cache and used frequently enough * in the executive to justify turning this on. * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ -#define CPU_STRUCTURE_ALIGNMENT +#define CPU_STRUCTURE_ALIGNMENT __attribute__ ((aligned (32))) /* * Define what is required to specify how the network to host conversion * routines are handled. * - * OR32 Specific Information: + * Or1k Specific Information: * - * XXX document implementation including references if appropriate + * This version of RTEMS is designed specifically to run with + * big endian architectures. If you want little endian, you'll + * have to make the appropriate adjustments here and write + * efficient routines for byte swapping. The Or1k architecture + * doesn't do this very well. */ #define CPU_HAS_OWN_HOST_TO_NETWORK_ROUTINES FALSE @@ -343,9 +332,6 @@ extern "C" { * interrupt field of the task mode. How those bits map to the * CPU interrupt levels is defined by the routine _CPU_ISR_Set_level(). * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ #define CPU_MODES_INTERRUPT_MASK 0x00000001 @@ -356,12 +342,8 @@ extern "C" { * Examples structures include the descriptor tables from the i386 * and the processor control structure on the i960ca. * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ -/* may need to put some structures here. */ /* * Contexts @@ -397,32 +379,85 @@ extern "C" { * this is enough information for RTEMS, it is probably not enough for * a debugger such as gdb. But that is another problem. * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate + * */ -typedef struct { - unsigned32 some_integer_register; - unsigned32 some_system_register; -} Context_Control; +#ifdef OR1K_64BIT_ARCH +#define or1kreg unsigned64 +#else +#define or1kreg unsigned32 +#endif -typedef struct { - double some_float_register; -} Context_Control_fp; +/* SR_MASK is the mask of values that will be copied to/from the status + register on a context switch. Some values, like the flag state, are + specific on the context, while others, such as interrupt enables, + are global. The currently defined global bits are: + + 0x00001 SUPV: Supervisor mode + 0x00002 EXR: Exceptions on/off + 0x00004 EIR: Interrupts enabled/disabled + 0x00008 DCE: Data cache enabled/disabled + 0x00010 ICE: Instruction cache enabled/disabled + 0x00020 DME: Data MMU enabled/disabled + 0x00040 IME: Instruction MMU enabled/disabled + 0x00080 LEE: Little/Big Endian enable + 0x00100 CE: Context ID/shadow regs enabled/disabled + 0x01000 OVE: Overflow causes exception + 0x04000 EP: Exceptions @ 0x0 or 0xF0000000 + 0x08000 PXR: Partial exception recognition enabled/disabled + 0x10000 SUMRA: SPR's accessible/inaccessible + + The context specific bits are: + + 0x00200 F Branch flag indicator + 0x00400 CY Carry flag indicator + 0x00800 OV Overflow flag indicator + 0x02000 DSX Delay slot exception occurred + 0xF8000000 CID Current Context ID +*/ + +#define SR_MASK 0xF8002E00 + +typedef enum { + SR_SUPV = 0x00001, + SR_EXR = 0x00002, + SR_EIR = 0x00004, + SR_DCE = 0x00008, + SR_ICE = 0x00010, + SR_DME = 0x00020, + SR_IME = 0x00040, + SR_LEE = 0x00080, + SR_CE = 0x00100, + SR_F = 0x00200, + SR_CY = 0x00400, + SR_OV = 0x00800, + SR_OVE = 0x01000, + SR_DSX = 0x02000, + SR_EP = 0x04000, + SR_PXR = 0x08000, + SR_SUMRA = 0x10000, + SR_CID = 0xF8000000, +} StatusRegisterBits; typedef struct { - unsigned32 special_interrupt_register; -} CPU_Interrupt_frame; + unsigned32 sr; /* Current status register non persistent values */ + unsigned32 esr; /* Saved exception status register */ + unsigned32 ear; /* Saved exception effective address register */ + unsigned32 epc; /* Saved exception PC register */ + or1kreg r[31]; /* Registers */ + or1kreg pc; /* Context PC 4 or 8 bytes for 64 bit alignment */ +} Context_Control; +typedef int Context_Control_fp; +typedef Context_Control CPU_Interrupt_frame; +#define _CPU_Null_fp_context 0 +#define _CPU_Interrupt_stack_low 0 +#define _CPU_Interrupt_stack_high 0 /* * The following table contains the information required to configure * the XXX processor specific parameters. * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ typedef struct { @@ -437,24 +472,17 @@ typedef struct { void * (*stack_allocate_hook)( unsigned32 ); void (*stack_free_hook)( void* ); /* end of fields required on all CPUs */ - } rtems_cpu_table; /* * Macros to access required entires in the CPU Table are in * the file rtems/system.h. * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ /* - * Macros to access OR32 specific additions to the CPU Table + * Macros to access OR1K specific additions to the CPU Table * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ /* There are no CPU specific additions to the CPU Table for this port. */ @@ -465,12 +493,9 @@ typedef struct { * _CPU_Initialize and copied into the task's FP context area during * _CPU_Context_Initialize. * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ -SCORE_EXTERN Context_Control_fp _CPU_Null_fp_context; +/* SCORE_EXTERN Context_Control_fp _CPU_Null_fp_context; */ /* * On some CPUs, RTEMS supports a software managed interrupt stack. @@ -484,13 +509,12 @@ SCORE_EXTERN Context_Control_fp _CPU_Null_fp_context; * NOTE: These two variables are required if the macro * CPU_HAS_SOFTWARE_INTERRUPT_STACK is defined as TRUE. * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ +/* SCORE_EXTERN void *_CPU_Interrupt_stack_low; SCORE_EXTERN void *_CPU_Interrupt_stack_high; +*/ /* * With some compilation systems, it is difficult if not impossible to @@ -501,9 +525,6 @@ SCORE_EXTERN void *_CPU_Interrupt_stack_high; * can make it easier to invoke that routine at the end of the interrupt * sequence (if a dispatch is necessary). * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)(); @@ -511,9 +532,6 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)(); /* * Nothing prevents the porter from declaring more CPU specific variables. * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ /* XXX: if needed, put more variables here */ @@ -524,21 +542,18 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)(); * area is not defined -- only the size is. This is usually on * CPUs with a "floating point save context" instruction. * - * OR32 Specific Information: + * Or1k Specific Information: * - * XXX document implementation including references if appropriate + * We don't support floating point in this version, so the size is 0 */ -#define CPU_CONTEXT_FP_SIZE sizeof( Context_Control_fp ) +#define CPU_CONTEXT_FP_SIZE 0 /* * Amount of extra stack (above minimum stack size) required by * MPCI receive server thread. Remember that in a multiprocessor * system this thread must exist and be able to process all directives. * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ #define CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK 0 @@ -547,39 +562,23 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)(); * This defines the number of entries in the ISR_Vector_table managed * by RTEMS. * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ -#define CPU_INTERRUPT_NUMBER_OF_VECTORS 32 +#define CPU_INTERRUPT_NUMBER_OF_VECTORS 16 #define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER (CPU_INTERRUPT_NUMBER_OF_VECTORS - 1) -/* - * This is defined if the port has a special way to report the ISR nesting - * level. Most ports maintain the variable _ISR_Nest_level. - */ - -#define CPU_PROVIDES_ISR_IS_IN_PROGRESS FALSE - /* * Should be large enough to run all RTEMS tests. This insures * that a "reasonable" small application should not have any problems. * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ -#define CPU_STACK_MINIMUM_SIZE (1024*4) +#define CPU_STACK_MINIMUM_SIZE 4096 /* * CPU's worst alignment requirement for data types on a byte boundary. This * alignment does not take into account the requirements for the stack. * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ #define CPU_ALIGNMENT 8 @@ -603,9 +602,6 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)(); * have to be greater or equal to than CPU_ALIGNMENT to ensure that * elements allocated from the heap meet all restrictions. * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ #define CPU_HEAP_ALIGNMENT CPU_ALIGNMENT @@ -621,9 +617,6 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)(); * NOTE: This does not have to be a power of 2. It does have to * be greater or equal to than CPU_ALIGNMENT. * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ #define CPU_PARTITION_ALIGNMENT CPU_ALIGNMENT @@ -636,34 +629,16 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)(); * * NOTE: This must be a power of 2 either 0 or greater than CPU_ALIGNMENT. * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ #define CPU_STACK_ALIGNMENT 0 -/* - * ISR handler macros - */ - -/* - * Support routine to initialize the RTEMS vector table after it is allocated. - * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate - */ - -#define _CPU_Initialize_vectors() +/* ISR handler macros */ /* * Disable all interrupts for an RTEMS critical section. The previous * level is returned in _level. * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ #define _CPU_ISR_Disable( _isr_cookie ) \ @@ -676,9 +651,6 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)(); * This indicates the end of an RTEMS critical section. The parameter * _level is not modified. * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ #define _CPU_ISR_Enable( _isr_cookie ) \ @@ -691,9 +663,6 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)(); * sections into two or more parts. The parameter _level is not * modified. * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ #define _CPU_ISR_Flash( _isr_cookie ) \ @@ -712,9 +681,6 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)(); * * The get routine usually must be implemented as a subroutine. * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ #define _CPU_ISR_Set_level( new_level ) \ @@ -747,14 +713,16 @@ unsigned32 _CPU_ISR_Get_level( void ); * FPU may be easily disabled by software such as on the SPARC * where the PSR contains an enable FPU bit. * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ #define _CPU_Context_Initialize( _the_context, _stack_base, _size, \ _isr, _entry_point, _is_fp ) \ { \ + memset(_the_context,'\0',sizeof(Context_Control)); \ + (_the_context)->r[1] = (unsigned32*) ((unsigned32) (_stack_base) + (_size) ); \ + (_the_context)->r[2] = (unsigned32*) ((unsigned32) (_stack_base)); \ + (_the_context)->sr = (_isr) ? 0x0000001B : 0x0000001F; \ + (_the_context)->pc = (unsigned32*) _entry_point ; \ } /* @@ -766,9 +734,6 @@ unsigned32 _CPU_ISR_Get_level( void ); * not work if restarting self conflicts with the stack frame * assumptions of restoring a context. * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ #define _CPU_Context_Restart_self( _the_context ) \ @@ -787,9 +752,6 @@ unsigned32 _CPU_ISR_Get_level( void ); * a "dump context" instruction which could fill in from high to low * or low to high based on the whim of the CPU designers. * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ #define _CPU_Context_Fp_start( _base, _offset ) \ @@ -806,9 +768,6 @@ unsigned32 _CPU_ISR_Get_level( void ); * Other models include (1) not doing anything, and (2) putting * a "null FP status word" in the correct place in the FP context. * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ #define _CPU_Context_Initialize_fp( _destination ) \ @@ -825,9 +784,6 @@ unsigned32 _CPU_ISR_Get_level( void ); * location or a register, optionally disables interrupts, and * halts/stops the CPU. * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ #define _CPU_Fatal_halt( _error ) \ @@ -892,23 +848,26 @@ unsigned32 _CPU_ISR_Get_level( void ); * where bit_set_table[ 16 ] has values which indicate the first * bit set * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ -#define CPU_USE_GENERIC_BITFIELD_CODE TRUE + /* #define CPU_USE_GENERIC_BITFIELD_CODE FALSE */ +#define CPU_USE_GENERIC_BITFIELD_CODE TRUE #define CPU_USE_GENERIC_BITFIELD_DATA TRUE #if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE) + /* Get a value between 0 and N where N is the bit size */ + /* This routine makes use of the fact that CPUCFGR defines + OB32S to have value 32, and OB64S to have value 64. If + this ever changes then this routine will fail. */ #define _CPU_Bitfield_Find_first_bit( _value, _output ) \ - { \ - (_output) = 0; /* do something to prevent warnings */ \ - } + asm volatile ("l.mfspr %0,r0,0x2 \n\t"\ + "l.andi %0,%0,0x60 \n\t"\ + "l.ff1 %1,%1,r0 \n\t"\ + "l.sub %0,%0,%1 \n\t" : "=&r" (_output), "+r" (_value)); #endif - + /* end of Bitfield handler macros */ /* @@ -916,15 +875,12 @@ unsigned32 _CPU_ISR_Get_level( void ); * as searched by _CPU_Bitfield_Find_first_bit(). See the discussion * for that routine. * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ #if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE) #define _CPU_Priority_Mask( _bit_number ) \ - ( 1 << (_bit_number) ) + (1 << _bit_number) #endif @@ -934,9 +890,6 @@ unsigned32 _CPU_ISR_Get_level( void ); * a major or minor component of a priority. See the discussion * for that routine. * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ #if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE) @@ -955,9 +908,6 @@ unsigned32 _CPU_ISR_Get_level( void ); * * This routine performs CPU dependent initialization. * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ void _CPU_Initialize( @@ -971,9 +921,6 @@ void _CPU_Initialize( * This routine installs a "raw" interrupt handler directly into the * processor's vector table. * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ void _CPU_ISR_install_raw_handler( @@ -987,7 +934,7 @@ void _CPU_ISR_install_raw_handler( * * This routine installs an interrupt vector. * - * OR32 Specific Information: + * NO_CPU Specific Information: * * XXX document implementation including references if appropriate */ @@ -1006,9 +953,6 @@ void _CPU_ISR_install_vector( * NOTE: It need only be provided if CPU_HAS_HARDWARE_INTERRUPT_STACK * is TRUE. * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ void _CPU_Install_interrupt_stack( void ); @@ -1021,9 +965,6 @@ void _CPU_Install_interrupt_stack( void ); * NOTE: It need only be provided if CPU_PROVIDES_IDLE_THREAD_BODY * is TRUE. * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ void _CPU_Thread_Idle_body( void ); @@ -1033,9 +974,10 @@ void _CPU_Thread_Idle_body( void ); * * This routine switches from the run context to the heir context. * - * OR32 Specific Information: + * Or1k Specific Information: * - * XXX document implementation including references if appropriate + * Please see the comments in the .c file for a description of how + * this function works. There are several things to be aware of. */ void _CPU_Context_switch( @@ -1051,9 +993,6 @@ void _CPU_Context_switch( * * NOTE: May be unnecessary to reload some registers. * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ void _CPU_Context_restore( @@ -1065,9 +1004,6 @@ void _CPU_Context_restore( * * This routine saves the floating point context passed to it. * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ void _CPU_Context_save_fp( @@ -1079,9 +1015,6 @@ void _CPU_Context_save_fp( * * This routine restores the floating point context passed to it. * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ void _CPU_Context_restore_fp( @@ -1107,9 +1040,6 @@ void _CPU_Context_restore_fp( * endianness for ALL fetches -- both code and data -- so the code * will be fetched incorrectly. * - * OR32 Specific Information: - * - * XXX document implementation including references if appropriate */ static inline unsigned int CPU_swap_u32( diff --git a/cpukit/score/cpu/or32/rtems/score/or32.h b/cpukit/score/cpu/or32/rtems/score/or32.h index 1aadcfc286..c996c046cf 100644 --- a/cpukit/score/cpu/or32/rtems/score/or32.h +++ b/cpukit/score/cpu/or32/rtems/score/or32.h @@ -1,10 +1,7 @@ -/* or32.h - * - * This file sets up basic CPU dependency settings based on - * compiler settings. For example, it can determine if - * floating point is available. This particular implementation - * is specified to the OPENCORES.ORG OR32 port. +/* or1k.h * + * This include file contains Or1k definitions pertaining to the Opencores + * or1k processor family. * * COPYRIGHT (c) 1989-1999. * On-Line Applications Research Corporation (OAR). @@ -13,12 +10,14 @@ * found in the file LICENSE in this distribution or at * http://www.OARcorp.com/rtems/license.html. * - * $Id$ + * This file adapted from no_cpu example of the RTEMS distribution. + * The body has been modified for the Opencores Or1k implementation by + * Chris Ziomkowski. * */ -#ifndef _INCLUDE_OR32_h -#define _INCLUDE_OR32_h +#ifndef _OR1K_H +#define _OR1K_H #ifdef __cplusplus extern "C" { @@ -26,7 +25,7 @@ extern "C" { /* * This file contains the information required to build - * RTEMS for a particular member of the OPENCORES.ORG OR32 family. + * RTEMS for a particular member of the or1k CPU family. * It does this by setting variables to indicate which * implementation dependent features are present in a particular * member of the family. @@ -43,16 +42,17 @@ extern "C" { */ #define CPU_MODEL_NAME "rtems_multilib" -#define OR32_HAS_FPU 1 +#define OR1K_HAS_FPU 1 -#elif defined(__or1k__) || defined(__OR1K__) +#elif defined(or1200) -#define CPU_MODEL_NAME "or32_model" -#define OR32_HAS_FPU 1 +#define CPU_MODEL_NAME "OR1200" +#define OR1K_HAS_FPU 0 #else -#error "Unsupported CPU Model" +#define CPU_MODEL_NAME "Generic Or1k Compatible" +#define OR1K_HAS_FPU 0 #endif @@ -60,11 +60,11 @@ extern "C" { * Define the name of the CPU family. */ -#define CPU_NAME "OPENCORES.ORG OR32" +#define CPU_NAME "OpenRisc 1000" #ifdef __cplusplus } #endif -#endif /* ! _INCLUDE_OR32_h */ +#endif /* ! _INCLUDE_NO_CPU_h */ /* end of include file */ diff --git a/cpukit/score/cpu/or32/rtems/score/types.h b/cpukit/score/cpu/or32/rtems/score/types.h index c20aa2068a..24978df4f9 100644 --- a/cpukit/score/cpu/or32/rtems/score/types.h +++ b/cpukit/score/cpu/or32/rtems/score/types.h @@ -1,7 +1,7 @@ -/* or32types.h +/* or1ktypes.h * - * This include file contains type definitions pertaining to the Intel - * or32 processor family. + * This include file contains type definitions pertaining to the Opencores + * or1k processor family. * * COPYRIGHT (c) 1989-1999. * On-Line Applications Research Corporation (OAR). @@ -10,11 +10,13 @@ * found in the file LICENSE in this distribution or at * http://www.OARcorp.com/rtems/license.html. * - * $Id$ + * This file adapted from no_cpu example of the RTEMS distribution. + * The body has been modified for the Opencores Or1k implementation by + * Chris Ziomkowski. */ -#ifndef __OR32_TYPES_h -#define __OR32_TYPES_h +#ifndef __OR1K_TYPES_h +#define __OR1K_TYPES_h #ifndef ASM @@ -43,8 +45,19 @@ typedef unsigned32 boolean; /* Boolean value */ typedef float single_precision; /* single precision float */ typedef double double_precision; /* double precision float */ -typedef void or32_isr; -typedef void ( *or32_isr_entry )( void ); +typedef void no_cpu_isr; +typedef void ( *no_cpu_isr_entry )( void ); + +/* + * Turns out the that the disable POSIX option doesn't work + * too well. Specifically, the libc library still wants to know + * these POSIX values. We'll go ahead and include them here + * until such time as someone like OAR who is familiar with this + * can figure out what should really be done. + */ + +#define NAME_MAX 255 +#define LINK_MAX 8 #ifdef __cplusplus } -- cgit v1.2.3