summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--c/src/exec/score/cpu/powerpc/TODO1
-rw-r--r--c/src/exec/score/cpu/powerpc/cpu.c29
-rw-r--r--c/src/exec/score/cpu/powerpc/cpu.h3
-rw-r--r--c/src/exec/score/cpu/powerpc/ppc.h10
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.
*/