[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