[PATCH] Add support for OpenRISC architecture.
Hesham Moustafa
heshamelmatary at gmail.com
Tue Aug 12 11:08:30 UTC 2014
On Mon, Aug 11, 2014 at 8:33 PM, Joel Sherrill
<joel.sherrill at oarcorp.com> wrote:
>
> On 8/11/2014 1:16 PM, Gedare Bloom wrote:
>> On Mon, Aug 11, 2014 at 8:03 AM, Hesham ALMatary
>> <heshamelmatary at gmail.com> wrote:
>>> This work is based on the old or32 port (that has been removed back in 2005)
>>> authored by Chris Ziomkowski. The patch includes the basic functions every
>>> port should implement like: context switch, exception handling,
>>> OpenRISC ABI and machine definitions and configurations.
>>> ---
>>> cpukit/configure.ac | 1 +
>>> cpukit/score/cpu/Makefile.am | 1 +
>>> cpukit/score/cpu/or1k/Makefile.am | 36 +
>>> cpukit/score/cpu/or1k/asm.h | 104 ++
>>> cpukit/score/cpu/or1k/cpu.c | 120 +++
>>> cpukit/score/cpu/or1k/or1k-context-initialize.c | 43 +
>>> cpukit/score/cpu/or1k/or1k-context-switch.S | 115 +++
>>> cpukit/score/cpu/or1k/or1k-exception-default.c | 24 +
>>> cpukit/score/cpu/or1k/or1k-exception-frame-print.c | 22 +
>>> cpukit/score/cpu/or1k/or1k-exception-handler-low.S | 285 ++++++
>>> cpukit/score/cpu/or1k/rtems/asm.h | 99 ++
>>> cpukit/score/cpu/or1k/rtems/score/cpu.h | 1049 ++++++++++++++++++++
>>> cpukit/score/cpu/or1k/rtems/score/cpu_asm.h | 74 ++
>>> cpukit/score/cpu/or1k/rtems/score/or1k-utility.h | 334 +++++++
>>> cpukit/score/cpu/or1k/rtems/score/or1k.h | 49 +
>>> cpukit/score/cpu/or1k/rtems/score/types.h | 51 +
>>> 16 files changed, 2407 insertions(+)
>>> create mode 100644 cpukit/score/cpu/or1k/Makefile.am
>>> create mode 100644 cpukit/score/cpu/or1k/asm.h
>>> create mode 100644 cpukit/score/cpu/or1k/cpu.c
>>> create mode 100644 cpukit/score/cpu/or1k/or1k-context-initialize.c
>>> create mode 100644 cpukit/score/cpu/or1k/or1k-context-switch.S
>>> create mode 100644 cpukit/score/cpu/or1k/or1k-exception-default.c
>>> create mode 100644 cpukit/score/cpu/or1k/or1k-exception-frame-print.c
>>> create mode 100644 cpukit/score/cpu/or1k/or1k-exception-handler-low.S
>>> create mode 100644 cpukit/score/cpu/or1k/rtems/asm.h
>> You have two of these asm.h files. You should only have this one.
>>
>>> create mode 100644 cpukit/score/cpu/or1k/rtems/score/cpu.h
>>> create mode 100644 cpukit/score/cpu/or1k/rtems/score/cpu_asm.h
>>> create mode 100644 cpukit/score/cpu/or1k/rtems/score/or1k-utility.h
>>> create mode 100644 cpukit/score/cpu/or1k/rtems/score/or1k.h
>>> create mode 100644 cpukit/score/cpu/or1k/rtems/score/types.h
>>>
>> [...]
>>> diff --git a/cpukit/score/cpu/or1k/cpu.c b/cpukit/score/cpu/or1k/cpu.c
>>> new file mode 100644
>>> index 0000000..05e4cd9
>>> --- /dev/null
>>> +++ b/cpukit/score/cpu/or1k/cpu.c
>>> @@ -0,0 +1,120 @@
>>> +/*
>>> + * Opencore OR1K CPU Dependent Source
>>> + *
>>> + * COPYRIGHT (c) 2014 Hesham ALMatary <heshamelmatary at gmail.com>
>>> + * COPYRIGHT (c) 1989-1999.
>>> + * On-Line Applications Research Corporation (OAR).
>>> + *
>>> + * The license and distribution terms for this file may be
>>> + * found in the file LICENSE in this distribution or at
>>> + * http://www.rtems.com/license/LICENSE.
>>> + *
>>> + */
>>> +
>>> +#include <rtems/system.h>
>>> +#include <rtems/score/isr.h>
>>> +#include <rtems/score/wkspace.h>
>>> +#include <bsp/linker-symbols.h>
>>> +
>>> +/**
>>> + * @brief Performs processor dependent initialization.
>>> + */
>>> +void _CPU_Initialize(void)
>>> +{
>>> + /* Do nothing */
>>> +}
>>> +
>>> +/**
>>> + * @brief Sets the hardware interrupt level by the level value.
>>> + *
>>> + * @param[in] level for or1k can only range over two values:
>>> + * 0 (enable interrupts) and 1 (disable interrupts). In future
>>> + * implementations if fast context switch is implemented, the level
>>> + * can range from 0 to 15. @see OpenRISC architecture manual.
>>> + *
>>> + */
>>> +inline void _CPU_ISR_Set_level(uint32_t level)
>>> +{
>>> + uint32_t sr = 0;
>>> + level = (level > 0)? 1 : 0;
>>> +
>>> + /* map level bit to or1k interrupt enable/disable bit in sr register */
>>> + level <<= CPU_OR1K_SPR_SR_SHAMT_IEE;
>>> +
>>> + sr = _OR1K_mfspr(CPU_OR1K_SPR_SR);
>>> +
>>> + if (level == 0) /* Enable all interrupts */
>>> + {
>>> + sr |= CPU_OR1K_SPR_SR_IEE | CPU_OR1K_SPR_SR_TEE;
>>> + }
>>> + else
>>> + {
>>> + sr &= CPU_OR1K_ISR_STATUS_MASK_I_DIS;
>>> + }
>> Put braces on same line as if/else, e.g.:
>> if ( level == 0 ) {
>> ...
>> } else {
>> ...
>> }
>>
>>> +
>>> + _OR1K_mtspr(CPU_OR1K_SPR_SR, sr);
>>> + }
>>> +
>>> +uint32_t _CPU_ISR_Get_level( void )
>>> +{
>>> + uint32_t sr = 0;
>>> +
>>> + sr = _OR1K_mfspr(CPU_OR1K_SPR_SR);
>>> +
>>> + return (sr & CPU_OR1K_SPR_SR_IEE)? 0 : 1;
>>> +}
>>> +
> Why aren't these static inlines?
>>> +void _CPU_ISR_install_raw_handler(
>>> + uint32_t vector,
>>> + proc_ptr new_handler,
>>> + proc_ptr *old_handler
>>> +)
>>> +{
>>> +
>>> +}
>>> +
>>> +void _CPU_ISR_install_vector(
>>> + uint32_t vector,
>>> + proc_ptr new_handler,
>>> + proc_ptr *old_handler
>>> +)
>>> +{
>>> + volatile proc_ptr *table =
>>> + (proc_ptr *) bsp_start_vector_table_begin;
>> Why is this volatile?
> Likely history.
>
>>> + proc_ptr current_handler;
>>> +
>>> + ISR_Level level;
>>> +
>>> + _ISR_Disable( level );
>>> +
>>> + current_handler = table [vector];
>>> +
>>> + /* The current handler is now the old one */
>>> + if (old_handler != NULL) {
>>> + *old_handler = (proc_ptr) current_handler;
>>> + }
>>> +
>>> + /* Write only if necessary to avoid writes to a maybe read-only memory */
>>> + if (current_handler != (uint32_t) new_handler) {
>>> + table [vector] = (uint32_t) new_handler;
>>> + }
>>> +
>>> + _ISR_Enable( level );
>>> +}
>>> +
>>> +void _CPU_Install_interrupt_stack( void )
>>> +{
>>> +}
>>> +
> How does the interrupt stack get installed? If the port doesn't do this,
> then there is a feature macro to avoid needing this routine.
>>> +void _CPU_Context_Initialize_fp(
>>> + void **fp_context_ptr
>>> +)
>>> +{
>>> +}
>>> +
> Is there an FPU? If not, then this is not needed.
>
> At the very least, it should be conditionally compiled based upon the
> presence
> of an FPU.
>>> +void _CPU_Thread_Idle_body( void )
>>> +{
>>> +
>>> + for( ; ; );
>>> + /* insert your "halt" instruction here */
>>> +}
>> [...]
> I would put this in another file since it can be overridden by the
> BSP or application.
>
> On top of this, this is not special and the port should define the
> feature macros for IDLE thread so it uses the generic IDLE loop
> provided by Score Thread.
>
> If there is not a low power/halt/sleep type instruction, then
> this code is unneeded since the generic one (_Thread_Idle_body)
> is available.
>>> diff --git a/cpukit/score/cpu/or1k/or1k-exception-handler-low.S b/cpukit/score/cpu/or1k/or1k-exception-handler-low.S
>>> new file mode 100644
>>> index 0000000..00da0ec
>>> --- /dev/null
>>> +++ b/cpukit/score/cpu/or1k/or1k-exception-handler-low.S
>>> @@ -0,0 +1,285 @@
>>> +/**
>>> + * @file
>>> + *
>>> + * @ingroup ScoreCPU
>>> + *
>>> + * @brief OR1K exception support implementation.
>>> + */
>>> +
>>> +/*
>>> + * COPYRIGHT (c) 2014 Hesham ALMatary <heshamelmatary at gmail.com>
>>> + *
>>> + * The license and distribution terms for this file may be
>>> + * found in the file LICENSE in this distribution or at
>>> + * http://www.rtems.org/license/LICENSE.
>>> + *
>>> + */
>>> +
>>> +#ifdef HAVE_CONFIG_H
>>> +#include "config.h"
>>> +#endif
>>> +
>>> +#include <rtems/asm.h>
>>> +#include <rtems/score/percpu.h>
>>> +#include "rtems/score/or1k-utility.h"
>>> +
>>> +.align 4
>>> +.text
>>> +PUBLIC(_ISR_Handler)
>>> +.type _ISR_Handler, at function
>>> +
>>> + SYM(_ISR_Handler):
>>> +
>>> + l.addi r1, r1, -140
>>> +
>>> + /* r3 is saved by BSP exception handler */
>>> + l.sw 16(r1),r4
>>> + l.sw 20(r1),r5
>>> + l.sw 24(r1),r6
>>> +
>>> + /* Save interrupted task stack pointer */
>>> + l.addi r4, r1, 144
>>> + l.sw 4(r1), r4
>>> +
>>> + /* Save interrupted task r3 (first arg) value */
>>> + l.addi r4, r1, 140
>>> + l.lwz r4, 0(r4)
>>> + l.sw 12(r1), r4
>>> +
>>> + /* Increment nesting level */
>>> + l.movhi r6, hi(ISR_NEST_LEVEL)
>>> + l.ori r6, r6, lo(ISR_NEST_LEVEL)
>>> + l.lwz r5, 0(r6)
>>> + l.addi r5, r5, 1
>>> + l.sw 0(r6), r5
>>> +
>>> + /* Disable multitasking */
>>> + l.movhi r6, hi(THREAD_DISPATCH_DISABLE_LEVEL)
>>> + l.ori r6, r6, lo(THREAD_DISPATCH_DISABLE_LEVEL)
>>> + l.lwz r5, 0(r6)
>>> + l.addi r5, r5, 1
>>> + l.sw 0(r6), r5
>>> +
> Simplicity first but if there is pipeline delay while the memory is loaded
> into a register, you can initiate the loads in parallel if you can arrange
> for different destination registers. I think the SPARC port does this.
Done.
>>> + l.sw 8(r1),r2
>>> +
>>> + l.sw 24(r1),r6
>>> + l.sw 28(r1),r7
>>> + l.sw 32(r1),r8
>>> + l.sw 36(r1),r9
>>> + l.sw 40(r1),r10
>>> + l.sw 44(r1),r11
>>> + l.sw 48(r1),r12
>>> + l.sw 52(r1),r13
>>> + l.sw 56(r1),r14
>>> + l.sw 60(r1),r15
>>> + l.sw 64(r1),r16
>>> + l.sw 68(r1),r17
>>> + l.sw 72(r1),r18
>>> + l.sw 76(r1),r19
>>> + l.sw 80(r1),r20
>>> + l.sw 84(r1),r21
>>> + l.sw 88(r1),r22
>>> + l.sw 92(r1),r23
>>> + l.sw 96(r1),r24
>>> + l.sw 100(r1),r25
>>> + l.sw 104(r1),r26
>>> + l.sw 108(r1),r27
>>> + l.sw 112(r1),r28
>>> + l.sw 116(r1),r29
>>> + l.sw 120(r1),r30
>>> + l.sw 124(r1),r31
>>> + /* Exception level related registers */
>>> +
> Out of curiosity, are there load/store double register instructions?
For 64-bit implementations, the maximum load instruction can deal with
only 64-bit, otherwise it's only 32-bit loads/stores and others deals
with half word, byte, signed and unsigned.
>>> + /* EPCR */
>>> + l.mfspr r13, r0, CPU_OR1K_SPR_EPCR0
>>> + l.sw 128(r1), r13 /* epcr */
>>> +
>>> + /* EEAR */
>>> + l.mfspr r13, r0, CPU_OR1K_SPR_EEAR0
>>> + l.sw 132(r1), r13 /* eear */
>>> +
>>> + /* ESR */
>>> + l.mfspr r13, r0, CPU_OR1K_SPR_ESR0
>>> + l.sw 136(r1), r13 /* esr */
>>> +
>>> + /* Keep r1 (Exception frame address) in r14 */
>>> + l.add r14, r1, r0
>>> +
>> I take it that r14 is a callee-save register?
>>
>>> + /* Call the exception handler from vector table */
>>> +
>>> + /* First function arg for C handler is vector number,
>>> + * and the second is a pointer to exception frame.
>>> + */
>>> + l.add r13, r3, r0
>>> + l.add r4, r1, r0
>>> + l.slli r13, r13, 2
>>> + l.addi r13, r13, lo(bsp_start_vector_table_begin)
>>> + l.lwz r13, 0(r13)
>>> +
>>> + /* Switch to RTEMS dedicated interrupt stack */
>>> + l.movhi r1, hi(INTERRUPT_STACK_HIGH)
>>> + l.ori r1, r1, lo(INTERRUPT_STACK_HIGH)
>>> + l.lwz r1, 0(r1)
>>> +
>> If this is a nested interrupt, you should not switch the stack, since
>> execution is already on the interrupt stack. Make a note of where you
>> store the pointer to the task stack (r14). I think saving the frame
>> pointer in r14 only has to be done if you switch the stack, since
>> otherwise you can obtain it by simple unwinding in the interrupt
>> stack.
> +1
>>> + l.jalr r13
>>> + l.nop
>>> +
>>> + SYM(exception_frame_restore):
>>> +
>>> + l.add r1, r14, r0
>> Add comment here that you are switching back to the interrupted stack.
>> Again, notice that it may not be needed if you don't switch stacks due
>> to nested interrupts.
>>
>>> +
>>> + /* Exception level related registers */
>>> +
>>> + /* EPCR */
>>> + l.lwz r13, 128(r1)
>>> + l.mtspr r0, r13, CPU_OR1K_SPR_EPCR0
>>> +
>>> + /* EEAR */
>>> + l.lwz r13, 132(r1)
>>> + l.mtspr r0, r13, CPU_OR1K_SPR_EEAR0
>>> +
>>> + /* ESR */
>>> + l.lwz r13, 136(r1)
>>> + l.mtspr r0, r13, CPU_OR1K_SPR_ESR0
>>> +
>>> + /* Decrement nesting level */
>>> + l.movhi r6, hi(ISR_NEST_LEVEL)
>>> + l.ori r6, r6, lo(ISR_NEST_LEVEL)
>>> + l.lwz r5, 0(r6)
>>> + l.addi r5, r5, -1
>>> + l.sw 0(r6), r5
>>> +
>>> + /* Enable multitasking */
>>> + l.movhi r6, hi(THREAD_DISPATCH_DISABLE_LEVEL)
>>> + l.ori r6, r6, lo(THREAD_DISPATCH_DISABLE_LEVEL)
>>> + l.lwz r5, 0(r6)
>>> + l.addi r5, r5, -1
>>> + l.sw 0(r6), r5
>>> +
>>> + l.lwz r2, 8(r1)
>>> + l.lwz r3, 12(r1)
>>> + l.lwz r4, 16(r1)
>>> + l.lwz r5, 20(r1)
>>> + l.lwz r6, 24(r1)
>>> + l.lwz r7, 28(r1)
>>> + l.lwz r8, 32(r1)
>>> + l.lwz r9, 36(r1)
>>> + l.lwz r10, 40(r1)
>>> + l.lwz r11, 44(r1)
>>> + l.lwz r12, 48(r1)
>>> + l.lwz r13, 52(r1)
>>> + l.lwz r14, 56(r1)
>>> + l.lwz r15, 60(r1)
>>> + l.lwz r16, 64(r1)
>>> + l.lwz r17, 68(r1)
>>> + l.lwz r18, 72(r1)
>>> + l.lwz r19, 76(r1)
>>> + l.lwz r20, 80(r1)
>>> + l.lwz r21, 84(r1)
>>> + l.lwz r22, 88(r1)
>>> + l.lwz r23, 92(r1)
>>> + l.lwz r24, 96(r1)
>>> + l.lwz r25, 100(r1)
>>> + l.lwz r26, 104(r1)
>>> + l.lwz r27, 108(r1)
>>> + l.lwz r28, 112(r1)
>>> + l.lwz r29, 116(r1)
>>> + l.lwz r30, 120(r1)
>>> +
>>> + l.movhi r31, hi(DISPATCH_NEEDED)
>>> + l.ori r31, r3, lo(DISPATCH_NEEDED)
>>> + l.lwz r31, 0(r31)
>>> + l.sfgtu r31, r0
>>> + l.lwz r31, 124(r1)
>>> + l.bf _ISR_Dispatch /* Thread dispatch necessary */
>>> + l.nop
>>> +
>>> + l.addi r1, r1, 140
>>> +
>>> + l.lwz r3, 0(r1)
>>> + l.addi r1, r1, 4
>>> +
>>> + l.rfe
>>> + l.nop
>>> +
>>> +PUBLIC(_ISR_Dispatch)
>>> +SYM (_ISR_Dispatch):
>>> +
>>> + l.sw 4(r1),r1
>>> + l.sw 8(r1),r2
>>> + l.sw 16(r1),r4
>>> + l.sw 20(r1),r5
>>> + l.sw 24(r1),r6
>>> + l.sw 28(r1),r7
>>> + l.sw 32(r1),r8
>>> + /* Skip r10 as it's preserved to be used by TLS */
>>> + /* The following set of registers are preserved across function calls */
>>> + l.sw 56(r1),r14
>>> + l.sw 64(r1),r16
>>> + l.sw 72(r1),r18
>>> + l.sw 80(r1),r20
>>> + l.sw 88(r1),r22
>>> + l.sw 96(r1),r24
>>> + l.sw 104(r1),r26
>>> + l.sw 112(r1),r28
>>> + l.sw 120(r1),r30
>>> +
>> You can probably avoid saving the context here and restoring it later,
>> by moving the DISPATCH_NEEDED check to before
>> exception_frame_restore(). Then you would just jump to
>> exception_frame_restore() after the call to _Thread_Dispatch(), and
>> you can get rid of this redundant code. Yes?
>>
>>> + l.movhi r13, hi(_Thread_Dispatch)
>>> + l.ori r13, r13, lo(_Thread_Dispatch)
>>> + l.jalr r13
>>> + l.nop
>>> +
>>> + /* Exception level related registers */
>>> +
>>> + /* EPCR */
>>> + l.lwz r13, 128(r1)
>>> + l.mtspr r0, r13, CPU_OR1K_SPR_EPCR0
>>> +
>>> + /* EEAR */
>>> + l.lwz r13, 132(r1)
>>> + l.mtspr r0, r13, CPU_OR1K_SPR_EEAR0
>>> +
>>> + /* ESR */
>>> + l.lwz r13, 136(r1)
>>> + l.mtspr r0, r13, CPU_OR1K_SPR_ESR0
>>> +
>>> + l.lwz r1, 4(r1)
>>> + l.lwz r2, 8(r1)
>>> + l.lwz r4, 12(r1)
>>> + l.lwz r4, 16(r1)
>>> + l.lwz r5, 20(r1)
>>> + l.lwz r6, 24(r1)
>>> + l.lwz r7, 28(r1)
>>> + l.lwz r8, 32(r1)
>>> + l.lwz r9, 36(r1)
>>> + l.lwz r10, 40(r1)
>>> + l.lwz r11, 44(r1)
>>> + l.lwz r12, 48(r1)
>>> + l.lwz r13, 52(r1)
>>> + l.lwz r14, 56(r1)
>>> + l.lwz r15, 60(r1)
>>> + l.lwz r16, 64(r1)
>>> + l.lwz r17, 68(r1)
>>> + l.lwz r18, 72(r1)
>>> + l.lwz r19, 76(r1)
>>> + l.lwz r20, 80(r1)
>>> + l.lwz r21, 84(r1)
>>> + l.lwz r22, 88(r1)
>>> + l.lwz r23, 92(r1)
>>> + l.lwz r24, 96(r1)
>>> + l.lwz r25, 100(r1)
>>> + l.lwz r26, 104(r1)
>>> + l.lwz r27, 108(r1)
>>> + l.lwz r28, 112(r1)
>>> + l.lwz r29, 116(r1)
>>> + l.lwz r30, 120(r1)
>>> + l.lwz r31, 124(r1)
>>> +
>>> + l.addi r1, r1, 140
>>> +
>>> + l.lwz r3, 0(r1)
>>> + l.addi r1, r1, 4
>>> +
>>> + l.rfe
>>> + l.nop
>>> +
>> [...]
>>
>>
>> (This is cpu.h):
>>> +/*
>>> + * Disable all interrupts for an RTEMS critical section. The previous
>>> + * level is returned in _level.
>>> + *
>>> + */
>>> +
>>> +static inline uint32_t or1k_interrupt_disable( void )
>>> +{
>>> + volatile uint32_t sr;
>>> +
>> Why is sr volatile?
>>
>>> + sr = _OR1K_mfspr(CPU_OR1K_SPR_SR);
>>> +
>>> + _OR1K_mtspr(CPU_OR1K_SPR_SR, (sr & CPU_OR1K_ISR_STATUS_MASK_I_DIS));
>>> +
>>> + return sr;
>>> +}
>>> +
>>> +static inline void or1k_interrupt_enable(uint32_t level)
>>> +{
>>> + volatile uint32_t sr;
>>> +
>> Ditto.
>>
>>> + /* Enable interrupts and restore rs */
>>> + sr = level | CPU_OR1K_SPR_SR_IEE | CPU_OR1K_SPR_SR_TEE;
>>> + _OR1K_mtspr(CPU_OR1K_SPR_SR, sr);
>>> +
>>> +}
>>> +
>>> +#define _CPU_ISR_Disable( _isr_cookie ) \
>>> + do{ \
>>> + _isr_cookie = or1k_interrupt_disable(); \
>>> + } while (0)
>>> +
>> For a one-line macro, you don't need this do-while construct. You did
>> it correctly below.
>>
>>> +/*
>>> + * Enable interrupts to the previous level (returned by _CPU_ISR_Disable).
>>> + * This indicates the end of an RTEMS critical section. The parameter
>>> + * _level is not modified.
>>> + *
>>> + */
>>> +
>>> +#define _CPU_ISR_Enable( _isr_cookie ) \
>>> + or1k_interrupt_enable( _isr_cookie )
>>> +
>>> +/*
>>> + * This temporarily restores the interrupt to _level before immediately
>>> + * disabling them again. This is used to divide long RTEMS critical
>>> + * sections into two or more parts. The parameter _level is not
>>> + * modified.
>>> + *
>>> + */
>>> +
>>> +#define _CPU_ISR_Flash( _isr_cookie ) \
>>> + { \
>>> + }
>>> +
>> Is there a reason you don't provide an ISR_Flash implementation? This
>> should just be an enable followed by disable in a do-while cpp macro.
>>
>>> +#define CPU_TIMESTAMP_USE_STRUCT_TIMESPEC TRUE
>>> +#define CPU_TIMESTAMP_USE_INT64 FALSE
>>> +#define CPU_TIMESTAMP_USE_INT64_INLINE FALSE
>>> +
>> Almost all CPUs in RTEMS are using int64. Is there a good reason not
>> to for or1k?
> Agreed. 64-bit math is generally faster than struct timespec math.
>>> diff --git a/cpukit/score/cpu/or1k/rtems/score/cpu_asm.h b/cpukit/score/cpu/or1k/rtems/score/cpu_asm.h
>>> new file mode 100644
>>> index 0000000..a5659f3
>>> --- /dev/null
>>> +++ b/cpukit/score/cpu/or1k/rtems/score/cpu_asm.h
>> What's the point of this file, it appears mostly empty to me and isn't
>> included anywhere.
> Should be included to account for differences in register names, etc
> between tool set
> versions. At least context switch and start code should be needing it.
>
> You need to look at another example port for what should be in here.
> Likely nothing is
> using it now though.
Almost all ports provide it empty like this.
>>> @@ -0,0 +1,74 @@
>>> +/**
>>> + * @file
>>> + *
>>> + * @brief OR1K Assembly File
>>> + *
>>> + * Very loose template for an include file for the cpu_asm.? file
>>> + * if it is implemented as a ".S" file (preprocessed by cpp) instead
>>> + * of a ".s" file (preprocessed by gm4 or gasp).
>>> + */
>>> +
>>> +/*
>>> + * COPYRIGHT (c) 1989-1999.
>>> + * On-Line Applications Research Corporation (OAR).
>>> + *
>>> + * The license and distribution terms for this file may be
>>> + * found in the file LICENSE in this distribution or at
>>> + * http://www.rtems.org/license/LICENSE.
>>> + *
>>> + */
>>> +
>>> +#ifndef _RTEMS_SCORE_CPU_ASM_H
>>> +#define _RTEMS_SCORE_CPU_ASM_H
>>> +
>>> +/* pull in the generated offsets */
>>> +
>>> +/*
>>> +#include <rtems/score/offsets.h>
>>> +*/
>>> +
>>> +/*
>>> + * Hardware General Registers
>>> + */
>>> +
>>> +/* put something here */
>>> +
>>> +/*
>>> + * Hardware Floating Point Registers
>>> + */
>>> +
>>> +/* put something here */
>>> +
>>> +/*
>>> + * Hardware Control Registers
>>> + */
>>> +
>>> +/* put something here */
>>> +
>>> +/*
>>> + * Calling Convention
>>> + */
>>> +
>>> +/* put something here */
>>> +
>>> +/*
>>> + * Temporary registers
>>> + */
>>> +
>>> +/* put something here */
>>> +
>>> +/*
>>> + * Floating Point Registers - SW Conventions
>>> + */
>>> +
>>> +/* put something here */
>>> +
>>> +/*
>>> + * Temporary floating point registers
>>> + */
>>> +
>>> +/* put something here */
>>> +
>>> +#endif
>>> +
>>> +/* end of file */
>>> diff --git a/cpukit/score/cpu/or1k/rtems/score/or1k-utility.h b/cpukit/score/cpu/or1k/rtems/score/or1k-utility.h
>>> new file mode 100644
>>> index 0000000..2187c63
>>> --- /dev/null
>>> +++ b/cpukit/score/cpu/or1k/rtems/score/or1k-utility.h
>>> +/* Used to disable interrupts */
>>> +#define CPU_OR1K_ISR_STATUS_MASK_I_DIS 0xFFFFFFFB
>>> +
>> This is just ~(CPU_OR1K_SPR_SR_IEE). I would just use that and get rid
>> of this macro.
>>
>>> +#ifndef ASM
>>> +
>>> +#include <stddef.h>
>>> +#include <stdint.h>
>>> +#include <stdbool.h>
>>> +
>>> +#ifdef __cplusplus
>>> +extern "C" {
>>> +#endif /* __cplusplus */
>>> +
>>> +/**
>>> + * @brief Supervision Mode registers definitions.
>>> + *
>>> + * @see OpenRISC architecture manual - revision 0.
>>> + */
> Somewhere put a link to the documentation in the Doxygen for the port.
>>> +typedef enum {
>>> + OR1K_EXCEPTION_RESET = 1,
>>> + OR1K_EXCEPTION_BUS_ERR = 2,
>>> + OR1K_EXCEPTION_D_PF = 3, /* Data Page Fault */
>>> + OR1K_EXCEPTION_I_PF = 4, /* Instruction Page Fault */
>>> + OR1K_EXCEPTION_TICK_TIMER = 5,
>>> + OR1K_EXCEPTION_ALIGNMENT = 6,
>>> + OR1K_EXCEPTION_I_UNDEF= 7, /* Undefiend instruction */
>>> + OR1K_EXCEPTION_IRQ = 8, /* External interrupt */
>>> + OR1K_EXCPETION_D_TLB = 9, /* Data TLB miss */
>>> + OR1K_EXCPETION_I_TLB = 10, /* Instruction TLB miss */
>>> + OR1K_EXCPETION_RANGE = 11, /* Range exception */
>>> + OR1K_EXCPETION_SYS_CALL = 12,
>>> + OR1K_EXCPETION_FP = 13, /* Floating point exception */
>>> + OR1K_EXCPETION_TRAP = 14, /* Caused by l.trap instruction or by debug unit */
>>> + OR1K_EXCPETION_RESERVED1 = 15,
>>> + OR1K_EXCPETION_RESERVED2 = 16,
>>> + OR1K_EXCPETION_RESERVED3 = 17,
>>> + MAX_EXCEPTIONS = 17,
>>> + OR1K_EXCEPTION_MAKE_ENUM_32_BIT = 0xffffffff
>>> +} OR1K_symbolic_exception_name;
>>> +
>> capitalize the S in symbolic.
>>
>>> +static inline uint32_t _OR1K_mfspr(uint32_t reg)
>>> +{
>>> + uint32_t spr_value;
>>> +
>>> + asm volatile (
>>> + "l.mfspr %1, r0, 0"
>>> + : "=r" (spr_value) : "r" (reg));
>> Something is wrong with your assembly here. I think you want to be
>> saying "l.mfspr spr_value, reg, 0"? This would be written as:
>> asm volatile("l.mfspr %0, %1, 0" : "=r" (spr_value) : "r" (reg));
>> Also, to make reading disassembly easier, you should put a \n\t at the
>> end of each line of assembly, i.e. "l.mfspr %0, %1, 0\n\t".
> FWIW the last time I built this port, there were warnings for inline
> asm's. The
> constraints didn't appear to be right. Are there warnings now?
>> -Gedare
>> _______________________________________________
>> devel mailing list
>> devel at rtems.org
>> http://lists.rtems.org/mailman/listinfo/devel
>
> --
> Joel Sherrill, Ph.D. Director of Research & Development
> joel.sherrill at OARcorp.com On-Line Applications Research
> Ask me about RTEMS: a free RTOS Huntsville AL 35805
> Support Available (256) 722-9985
>
More information about the devel
mailing list