[PATCH] Add support for OpenRISC architecture.
Gedare Bloom
gedare at rtems.org
Mon Aug 11 18:16:43 UTC 2014
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;
> +}
> +
> +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?
> + 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 )
> +{
> +}
> +
> +void _CPU_Context_Initialize_fp(
> + void **fp_context_ptr
> +)
> +{
> +}
> +
> +void _CPU_Thread_Idle_body( void )
> +{
> +
> + for( ; ; );
> + /* insert your "halt" instruction here */
> +}
[...]
> 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
> +
> + 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 */
> +
> + /* 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.
> + 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?
> 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.
> @@ -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.
> + */
> +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".
-Gedare
More information about the devel
mailing list