2002-08-05 Chris Ziomkowski <chris@asics.ws>

* asm.h, cpu.c, cpu_asm.c, rtems/score/cpu.h, rtems/score/or32.h,
	rtems/score/types.h: Merged from OpenCores CVS repository.
This commit is contained in:
Joel Sherrill
2002-08-05 19:19:45 +00:00
parent bf1f6531b8
commit 098755b36f
8 changed files with 649 additions and 298 deletions

View File

@@ -1,3 +1,8 @@
2002-08-05 Chris Ziomkowski <chris@asics.ws>
* 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 <corsepiu@faw.uni-ulm.de>
* Makefile.am: Build libscorecpu.a instead of rtems-cpu.rel.

View File

@@ -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 <rtems/score/cpuopts.h>
#include <rtems/score/or32.h>
#include <rtems/score/targopts.h>
#include <rtems/score/or1k.h>
/*
* 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 */

View File

@@ -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. <chris@asics.ws>
*/
#include <rtems/system.h>
@@ -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 )

View File

@@ -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. <chris@asics.ws>
*/
/*
@@ -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.
*/
}

View File

@@ -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 <rtems/score/cpuopts.h>
#include <rtems/score/or32.h>
#include <rtems/score/targopts.h>
#include <rtems/score/or1k.h>
/*
* 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 */

View File

@@ -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. <chris@asics.ws>
*
*/
#ifndef __CPU_h
#define __CPU_h
#ifndef _OR1K_CPU_h
#define _OR1K_CPU_h
#ifdef __cplusplus
extern "C" {
#endif
#include <rtems/score/or32.h> /* pick up machine definitions */
#include "rtems/score/or1k.h" /* pick up machine definitions */
#ifndef ASM
#include <rtems/score/types.h>
#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
*
*/
#ifdef OR1K_64BIT_ARCH
#define or1kreg unsigned64
#else
#define or1kreg unsigned32
#endif
/* 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 some_integer_register;
unsigned32 some_system_register;
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 struct {
double some_float_register;
} Context_Control_fp;
typedef struct {
unsigned32 special_interrupt_register;
} CPU_Interrupt_frame;
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(

View File

@@ -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. <chris@asics.ws>
*
*/
#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 */

View File

@@ -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. <chris@asics.ws>
*/
#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
}