diff options
Diffstat (limited to 'c/src/exec')
-rw-r--r-- | c/src/exec/score/cpu/powerpc/TODO | 1 | ||||
-rw-r--r-- | c/src/exec/score/cpu/powerpc/cpu.c | 29 | ||||
-rw-r--r-- | c/src/exec/score/cpu/powerpc/cpu.h | 3 | ||||
-rw-r--r-- | c/src/exec/score/cpu/powerpc/ppc.h | 10 |
4 files changed, 42 insertions, 1 deletions
diff --git a/c/src/exec/score/cpu/powerpc/TODO b/c/src/exec/score/cpu/powerpc/TODO index 6e3e04e6ca..64c96cb14c 100644 --- a/c/src/exec/score/cpu/powerpc/TODO +++ b/c/src/exec/score/cpu/powerpc/TODO @@ -5,3 +5,4 @@ Todo list: Maybe decode external interrupts like the HPPA does. + See c/src/lib/libcpu/powerpc/ppc403/ictrl/* for implementation on ppc403 diff --git a/c/src/exec/score/cpu/powerpc/cpu.c b/c/src/exec/score/cpu/powerpc/cpu.c index 676e330e5f..da6ecf4d19 100644 --- a/c/src/exec/score/cpu/powerpc/cpu.c +++ b/c/src/exec/score/cpu/powerpc/cpu.c @@ -33,6 +33,7 @@ #include <rtems/score/isr.h> #include <rtems/score/context.h> #include <rtems/score/thread.h> +#include <rtems/score/interr.h> /* * These are for testing purposes. @@ -474,6 +475,12 @@ void _CPU_ISR_install_raw_handler( * Set u32_handler = to target address */ u32_handler = slot->b_Handler & 0x03fffffc; + + /* IMD FIX: sign extend address fragment... */ + if (u32_handler & 0x02000000) { + u32_handler |= 0xfc000000; + } + *old_handler = (proc_ptr) u32_handler; } else *old_handler = 0; @@ -484,6 +491,21 @@ void _CPU_ISR_install_raw_handler( *slot = _CPU_Trap_slot_template; u32_handler = (unsigned32) new_handler; + + /* + * IMD FIX: insert address fragment only (bits 6..29) + * therefore check for proper address range + * and remove unwanted bits + */ + if ((u32_handler & 0xfc000000) == 0xfc000000) { + u32_handler &= ~0xfc000000; + } + else if ((u32_handler & 0xfc000000) != 0x00000000) { + _Internal_error_Occurred(INTERNAL_ERROR_CORE, + TRUE, + u32_handler); + } + slot->b_Handler |= u32_handler; slot->li_r0_IRQ |= vector; @@ -495,13 +517,20 @@ unsigned32 ppc_exception_vector_addr( unsigned32 vector ) { +#if (!PPC_HAS_EVPR) unsigned32 Msr; +#endif unsigned32 Top = 0; unsigned32 Offset = 0x000; +#if (PPC_HAS_EXCEPTION_PREFIX) _CPU_MSR_Value ( Msr ); if ( ( Msr & PPC_MSR_EP) != 0 ) /* Vectors at FFFx_xxxx */ Top = 0xfff00000; +#elif (PPC_HAS_EVPR) + asm volatile( "mfspr %0,0x3d6" : "=r" (Top)); /* EVPR */ + Top = Top & 0xffff0000; +#endif switch ( vector ) { case PPC_IRQ_SYSTEM_RESET: /* on 40x aka PPC_IRQ_CRIT */ diff --git a/c/src/exec/score/cpu/powerpc/cpu.h b/c/src/exec/score/cpu/powerpc/cpu.h index 6288b3e20a..1240f68451 100644 --- a/c/src/exec/score/cpu/powerpc/cpu.h +++ b/c/src/exec/score/cpu/powerpc/cpu.h @@ -481,7 +481,8 @@ typedef struct { boolean serial_cts_rts; unsigned32 serial_rate; unsigned32 timer_average_overhead; /* Average overhead of timer in ticks */ - unsigned32 timer_least_valid; /* Least valid number from timer */ + unsigned32 timer_least_valid; /* Least valid number from timer */ + boolean timer_internal_clock; /* TRUE, when timer runs with CPU clk */ #endif } rtems_cpu_table; diff --git a/c/src/exec/score/cpu/powerpc/ppc.h b/c/src/exec/score/cpu/powerpc/ppc.h index 56fd820709..a4b091c430 100644 --- a/c/src/exec/score/cpu/powerpc/ppc.h +++ b/c/src/exec/score/cpu/powerpc/ppc.h @@ -112,6 +112,7 @@ extern "C" { #define PPC_DEBUG_MODEL PPC_DEBUG_MODEL_IBM4xx #define PPC_HAS_EXCEPTION_PREFIX 0 +#define PPC_HAS_EVPR 1 #elif defined(ppc601) /* @@ -287,6 +288,15 @@ extern "C" { #endif /* + * Unless otherwise specified, assume the model does NOT have + * 403 style EVPR register to set the exception address prefix. + */ + +#ifndef PPC_HAS_EVPR +#define PPC_HAS_EVPR 0 +#endif + +/* * If no low power mode model was specified, then assume there is none. */ |