summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libcpu/powerpc/ppc403
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libcpu/powerpc/ppc403')
-rw-r--r--c/src/lib/libcpu/powerpc/ppc403/README22
-rw-r--r--c/src/lib/libcpu/powerpc/ppc403/clock/clock.c265
-rw-r--r--c/src/lib/libcpu/powerpc/ppc403/console/console.c387
-rw-r--r--c/src/lib/libcpu/powerpc/ppc403/timer/timer.c98
-rw-r--r--c/src/lib/libcpu/powerpc/ppc403/vectors/README25
-rw-r--r--c/src/lib/libcpu/powerpc/ppc403/vectors/align_h.s433
-rw-r--r--c/src/lib/libcpu/powerpc/ppc403/vectors/vectors.s282
7 files changed, 1512 insertions, 0 deletions
diff --git a/c/src/lib/libcpu/powerpc/ppc403/README b/c/src/lib/libcpu/powerpc/ppc403/README
new file mode 100644
index 0000000000..528506d3dd
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/ppc403/README
@@ -0,0 +1,22 @@
+#
+# $Id$
+#
+
+Various non BSP dependant support routines.
+
+clock - Uses the 403 PIT (Programmable interval timer) to
+ generate RTEMS clock ticks.
+
+console - Uses the 403 Internal serial port to do RTEMS
+ console I/O. Not ALL members of the 403 family
+ have this.
+
+include - Currently empty
+
+timer - Uses the 403 timebase register for timing
+ tests. Other PowerPCs have slightly different
+ timebase register definitions.
+
+vectors - PowerPC 403 specific vector entry points.
+ Includes CPU dependant, application independant
+ handlers: alignment.
diff --git a/c/src/lib/libcpu/powerpc/ppc403/clock/clock.c b/c/src/lib/libcpu/powerpc/ppc403/clock/clock.c
new file mode 100644
index 0000000000..068cf4f538
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/ppc403/clock/clock.c
@@ -0,0 +1,265 @@
+/* clock.c
+ *
+ * This routine initializes the interval timer on the
+ * PowerPC 403 CPU. The tick frequency is specified by the bsp.
+ *
+ * Author: Andrew Bray <andy@i-cubed.co.uk>
+ *
+ * COPYRIGHT (c) 1995 by i-cubed ltd.
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of i-cubed limited not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * i-cubed limited makes no representations about the suitability
+ * of this software for any purpose.
+ *
+ * Derived from c/src/lib/libcpu/hppa1_1/clock/clock.c:
+ *
+ * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ * On-Line Applications Research Corporation (OAR).
+ * All rights assigned to U.S. Government, 1994.
+ *
+ * This material may be reproduced by or for the U.S. Government pursuant
+ * to the copyright license under the clause at DFARS 252.227-7013. This
+ * notice must appear in all copies of this file and its derivatives.
+ *
+ * $Id$
+ */
+
+#include <bsp.h>
+#include <clockdrv.h>
+#include <rtems/libio.h>
+
+#include <stdlib.h> /* for atexit() */
+
+extern rtems_cpu_table Cpu_table; /* owned by BSP */
+
+volatile rtems_unsigned32 Clock_driver_ticks;
+static rtems_unsigned32 pit_value, tick_time;
+static rtems_boolean auto_restart;
+
+void Clock_exit( void );
+
+/*
+ * These are set by clock driver during its init
+ */
+
+rtems_device_major_number rtems_clock_major = ~0;
+rtems_device_minor_number rtems_clock_minor;
+
+static INLINE rtems_unsigned32 get_itimer(void)
+{
+ register rtems_unsigned32 rc;
+
+ asm volatile ("mfspr %0, 0x3dd" : "=r" ((rc))); /* TBLO */
+
+ return rc;
+}
+
+/*
+ * ISR Handler
+ */
+
+rtems_isr
+Clock_isr(rtems_vector_number vector)
+{
+ if (!auto_restart)
+ {
+ rtems_unsigned32 clicks_til_next_interrupt;
+ rtems_unsigned32 itimer_value;
+
+ /*
+ * setup for next interrupt; making sure the new value is reasonably
+ * in the future.... in case we lost out on an interrupt somehow
+ */
+
+ itimer_value = get_itimer();
+ tick_time += pit_value;
+
+ /*
+ * how far away is next interrupt *really*
+ * It may be a long time; this subtraction works even if
+ * Clock_clicks_interrupt < Clock_clicks_low_order via
+ * the miracle of unsigned math.
+ */
+ clicks_til_next_interrupt = tick_time - itimer_value;
+
+ /*
+ * If it is too soon then bump it up.
+ * This should only happen if CPU_HPPA_CLICKS_PER_TICK is too small.
+ * But setting it low is useful for debug, so...
+ */
+
+ if (clicks_til_next_interrupt < 400)
+ {
+ tick_time = itimer_value + 1000;
+ clicks_til_next_interrupt = 1000;
+ /* XXX: count these! this should be rare */
+ }
+
+ /*
+ * If it is too late, that means we missed the interrupt somehow.
+ * Rather than wait 35-50s for a wrap, we just fudge it here.
+ */
+
+ if (clicks_til_next_interrupt > pit_value)
+ {
+ tick_time = itimer_value + 1000;
+ clicks_til_next_interrupt = 1000;
+ /* XXX: count these! this should never happen :-) */
+ }
+
+ asm volatile ("mtspr 0x3db, %0" :: "r"
+ (clicks_til_next_interrupt)); /* PIT */
+ }
+
+ asm volatile ( "mtspr 0x3d8, %0" :: "r" (0x08000000)); /* TSR */
+
+ Clock_driver_ticks++;
+
+ rtems_clock_tick();
+}
+
+void Install_clock(rtems_isr_entry clock_isr)
+{
+ rtems_isr_entry previous_isr;
+ rtems_unsigned32 pvr, iocr;
+
+ Clock_driver_ticks = 0;
+
+ asm volatile ("mfdcr %0, 0xa0" : "=r" (iocr)); /* IOCR */
+ iocr &= ~4;
+ iocr |= 4; /* Select external timer clock */
+ asm volatile ("mtdcr 0xa0, %0" : "=r" (iocr) : "0" (iocr)); /* IOCR */
+
+ asm volatile ("mfspr %0, 0x11f" : "=r" ((pvr))); /* PVR */
+
+ if (((pvr & 0xffff0000) >> 16) != 0x0020)
+ return; /* Not a ppc403 */
+
+ if ((pvr & 0xff00) == 0x0000) /* 403GA */
+ auto_restart = (pvr & 0x00f0) > 0x0000 ? 1 : 0;
+ else if ((pvr & 0xff00) == 0x0100) /* 403GB */
+ auto_restart = 1;
+
+ pit_value = BSP_Configuration.microseconds_per_tick *
+ Cpu_table.clicks_per_usec;
+
+ if (BSP_Configuration.ticks_per_timeslice)
+ {
+ register rtems_unsigned32 tcr;
+
+ /*
+ * initialize the interval here
+ * First tick is set to right amount of time in the future
+ * Future ticks will be incremented over last value set
+ * in order to provide consistent clicks in the face of
+ * interrupt overhead
+ */
+
+ rtems_interrupt_catch(clock_isr, PPC_IRQ_PIT, &previous_isr);
+
+ asm volatile ("mtspr 0x3db, %0" : : "r" (pit_value)); /* PIT */
+
+ asm volatile ("mfspr %0, 0x3da" : "=r" ((tcr))); /* TCR */
+
+ tcr &= ~ 0x04400000;
+
+ tcr |= (auto_restart ? 0x04400000 : 0x04000000);
+
+ tick_time = get_itimer() + pit_value;
+
+ asm volatile ("mtspr 0x3da, %0" : "=r" ((tcr)) : "0" ((tcr))); /* TCR */
+ }
+ atexit(Clock_exit);
+}
+
+void
+ReInstall_clock(rtems_isr_entry new_clock_isr)
+{
+ rtems_isr_entry previous_isr;
+ rtems_unsigned32 isrlevel = 0;
+
+ rtems_interrupt_disable(isrlevel);
+
+ rtems_interrupt_catch(new_clock_isr, PPC_IRQ_PIT, &previous_isr);
+
+ rtems_interrupt_enable(isrlevel);
+}
+
+
+/*
+ * Called via atexit()
+ * Remove the clock interrupt handler by setting handler to NULL
+ */
+
+void
+Clock_exit(void)
+{
+ if ( BSP_Configuration.ticks_per_timeslice )
+ {
+ register rtems_unsigned32 tcr;
+
+ asm volatile ("mfspr %0, 0x3da" : "=r" ((tcr))); /* TCR */
+
+ tcr &= ~ 0x04400000;
+
+ asm volatile ("mtspr 0x3da, %0" : "=r" ((tcr)) : "0" ((tcr))); /* TCR */
+
+ (void) set_vector(0, PPC_IRQ_PIT, 1);
+ }
+
+}
+
+rtems_device_driver Clock_initialize(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *pargp
+)
+{
+ Install_clock( Clock_isr );
+
+ /*
+ * make major/minor avail to others such as shared memory driver
+ */
+
+ rtems_clock_major = major;
+ rtems_clock_minor = minor;
+
+ return RTEMS_SUCCESSFUL;
+}
+
+rtems_device_driver Clock_control(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *pargp
+)
+{
+ rtems_libio_ioctl_args_t *args = pargp;
+
+ if (args == 0)
+ goto done;
+
+ /*
+ * This is hokey, but until we get a defined interface
+ * to do this, it will just be this simple...
+ */
+
+ if (args->command == rtems_build_name('I', 'S', 'R', ' '))
+ {
+ Clock_isr(PPC_IRQ_PIT);
+ }
+ else if (args->command == rtems_build_name('N', 'E', 'W', ' '))
+ {
+ ReInstall_clock(args->buffer);
+ }
+
+done:
+ return RTEMS_SUCCESSFUL;
+}
+
diff --git a/c/src/lib/libcpu/powerpc/ppc403/console/console.c b/c/src/lib/libcpu/powerpc/ppc403/console/console.c
new file mode 100644
index 0000000000..7a3b1b425a
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/ppc403/console/console.c
@@ -0,0 +1,387 @@
+/*
+ * This file contains the PowerPC 403GA console IO package.
+ *
+ * Author: Andrew Bray <andy@i-cubed.co.uk>
+ *
+ * COPYRIGHT (c) 1995 by i-cubed ltd.
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of i-cubed limited not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * i-cubed limited makes no representations about the suitability
+ * of this software for any purpose.
+ *
+ * Derived from c/src/lib/libbsp/no_cpu/no_bsp/console/console.c:
+ *
+ * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ * On-Line Applications Research Corporation (OAR).
+ * All rights assigned to U.S. Government, 1994.
+ *
+ * This material may be reproduced by or for the U.S. Government pursuant
+ * to the copyright license under the clause at DFARS 252.227-7013. This
+ * notice must appear in all copies of this file and its derivatives.
+ *
+ * $Id$
+ */
+
+#define NO_BSP_INIT
+
+#include <bsp.h>
+#include <rtems/libio.h>
+
+extern rtems_cpu_table Cpu_table; /* owned by BSP */
+
+struct async {
+/*-----------------------------------------------------------------------------+
+| Line Status Register.
++-----------------------------------------------------------------------------*/
+ unsigned char SPLS;
+ unsigned char SPLSset;
+#define LSRDataReady 0x80
+#define LSRFramingError 0x40
+#define LSROverrunError 0x20
+#define LSRParityError 0x10
+#define LSRBreakInterrupt 0x08
+#define LSRTxHoldEmpty 0x04
+#define LSRTxShiftEmpty 0x02
+
+/*-----------------------------------------------------------------------------+
+| Handshake Status Register.
++-----------------------------------------------------------------------------*/
+ unsigned char SPHS;
+ unsigned char SPHSset;
+#define HSRDsr 0x80
+#define HSRCts 0x40
+
+/*-----------------------------------------------------------------------------+
+| Baud rate divisor registers
++-----------------------------------------------------------------------------*/
+ unsigned char BRDH;
+ unsigned char BRDL;
+
+/*-----------------------------------------------------------------------------+
+| Control Register.
++-----------------------------------------------------------------------------*/
+ unsigned char SPCTL;
+#define CRNormal 0x00
+#define CRLoopback 0x40
+#define CRAutoEcho 0x80
+#define CRDtr 0x20
+#define CRRts 0x10
+#define CRWordLength7 0x00
+#define CRWordLength8 0x08
+#define CRParityDisable 0x00
+#define CRParityEnable 0x04
+#define CREvenParity 0x00
+#define CROddParity 0x02
+#define CRStopBitsOne 0x00
+#define CRStopBitsTwo 0x01
+#define CRDisableDtrRts 0x00
+
+/*-----------------------------------------------------------------------------+
+| Receiver Command Register.
++-----------------------------------------------------------------------------*/
+ unsigned char SPRC;
+#define RCRDisable 0x00
+#define RCREnable 0x80
+#define RCRIntDisable 0x00
+#define RCRIntEnabled 0x20
+#define RCRDMACh2 0x40
+#define RCRDMACh3 0x60
+#define RCRErrorInt 0x10
+#define RCRPauseEnable 0x08
+
+/*-----------------------------------------------------------------------------+
+| Transmitter Command Register.
++-----------------------------------------------------------------------------*/
+ unsigned char SPTC;
+#define TCRDisable 0x00
+#define TCREnable 0x80
+#define TCRIntDisable 0x00
+#define TCRIntEnabled 0x20
+#define TCRDMACh2 0x40
+#define TCRDMACh3 0x60
+#define TCRTxEmpty 0x10
+#define TCRErrorInt 0x08
+#define TCRStopPause 0x04
+#define TCRBreakGen 0x02
+
+/*-----------------------------------------------------------------------------+
+| Miscellanies defines.
++-----------------------------------------------------------------------------*/
+ unsigned char SPTB;
+#define SPRB SPTB
+};
+
+#define XOFFchar 0x13
+#define XONchar 0x11
+
+typedef volatile struct async *pasync;
+static const pasync port = (pasync)0x40000000;
+
+/* console_initialize
+ *
+ * This routine initializes the console IO driver.
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ *
+ * Return values:
+ */
+
+rtems_device_driver console_initialize(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg
+)
+{
+ rtems_status_code status;
+ register unsigned tmp;
+
+ /* Initialise the serial port */
+ asm volatile ("mfdcr %0, 0xa0" : "=r" (tmp)); /* IOCR */
+ tmp &= ~3;
+ tmp |= (Cpu_table.serial_external_clock ? 2 : 0) |
+ (Cpu_table.serial_cts_rts ? 1 : 0);
+ asm volatile ("mtdcr 0xa0, %0" : "=r" (tmp) : "0" (tmp)); /* IOCR */
+ port->SPLS = (LSRDataReady | LSRFramingError | LSROverrunError |
+ LSRParityError | LSRBreakInterrupt);
+ tmp = Cpu_table.serial_per_sec / Cpu_table.serial_rate;
+ tmp = ((tmp + 8) >> 4) - 1;
+ port->BRDL = tmp & 0x255;
+ port->BRDH = tmp >> 8;
+ port->SPCTL = (CRNormal | CRDtr | CRRts | CRWordLength8 | CRParityDisable |
+ CRStopBitsOne);
+ port->SPRC = (RCREnable | RCRIntDisable | RCRPauseEnable);
+ port->SPTC = (TCREnable | TCRIntDisable);
+ port->SPHS = (HSRDsr | HSRCts);
+
+ status = rtems_io_register_name(
+ "/dev/console",
+ major,
+ (rtems_device_minor_number) 0
+ );
+
+ if (status != RTEMS_SUCCESSFUL)
+ rtems_fatal_error_occurred(status);
+
+ return RTEMS_SUCCESSFUL;
+}
+
+
+/* is_character_ready
+ *
+ * This routine returns TRUE if a character is available.
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ *
+ * Return values:
+ */
+
+rtems_boolean is_character_ready(
+ char *ch
+)
+{
+ unsigned char status;
+
+ if ((status = port->SPLS) & LSRDataReady)
+ {
+ *ch = port->SPRB;
+ return(TRUE);
+ }
+
+ /* Clean any dodgy status */
+ if ((status & (LSRFramingError | LSROverrunError | LSRParityError |
+ LSRBreakInterrupt)) != 0)
+ {
+ port->SPLS = (LSRFramingError | LSROverrunError | LSRParityError |
+ LSRBreakInterrupt);
+ }
+
+ return FALSE;
+}
+
+/* inbyte
+ *
+ * This routine reads a character from the SOURCE.
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ *
+ * Return values:
+ * character read from SOURCE
+ */
+
+char inbyte( void )
+{
+ unsigned char status;
+
+ while (1)
+ {
+ if ((status = port->SPLS) & LSRDataReady)
+ break;
+
+ /* Clean any dodgy status */
+ if ((status & (LSRFramingError | LSROverrunError | LSRParityError |
+ LSRBreakInterrupt)) != 0)
+ {
+ port->SPLS = (LSRFramingError | LSROverrunError | LSRParityError |
+ LSRBreakInterrupt);
+ }
+ }
+
+ return port->SPRB;
+}
+
+/* outbyte
+ *
+ * This routine transmits a character out the SOURCE. It may support
+ * XON/XOFF flow control.
+ *
+ * Input parameters:
+ * ch - character to be transmitted
+ *
+ * Output parameters: NONE
+ */
+
+void outbyte(
+ char ch
+)
+{
+ unsigned char status;
+
+ while (port->SPHS)
+ port->SPHS = (HSRDsr | HSRCts);
+
+ while (1)
+ {
+ status = port->SPLS;
+
+ if (port->SPHS)
+ port->SPHS = (HSRDsr | HSRCts);
+ else if (status & LSRTxHoldEmpty)
+ break;
+ }
+
+ if (Cpu_table.serial_xon_xoff)
+ while (is_character_ready(&status))
+ {
+ if (status == XOFFchar)
+ do {
+ while (!is_character_ready(&status));
+ } while (status != XONchar);
+ }
+
+ port->SPTB = ch;
+}
+
+/*
+ * Open entry point
+ */
+
+rtems_device_driver console_open(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+ return RTEMS_SUCCESSFUL;
+}
+
+/*
+ * Close entry point
+ */
+
+rtems_device_driver console_close(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+ return RTEMS_SUCCESSFUL;
+}
+
+/*
+ * read bytes from the serial port. We only have stdin.
+ */
+
+rtems_device_driver console_read(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+ rtems_libio_rw_args_t *rw_args;
+ char *buffer;
+ int maximum;
+ int count = 0;
+
+ rw_args = (rtems_libio_rw_args_t *) arg;
+
+ buffer = rw_args->buffer;
+ maximum = rw_args->count;
+
+ for (count = 0; count < maximum; count++) {
+ buffer[ count ] = inbyte();
+ if (buffer[ count ] == '\n' || buffer[ count ] == '\r') {
+ buffer[ count++ ] = '\n';
+ buffer[ count ] = 0;
+ break;
+ }
+ }
+
+ rw_args->bytes_moved = count;
+ return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED;
+}
+
+/*
+ * write bytes to the serial port. Stdout and stderr are the same.
+ */
+
+rtems_device_driver console_write(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+ int count;
+ int maximum;
+ rtems_libio_rw_args_t *rw_args;
+ char *buffer;
+
+ rw_args = (rtems_libio_rw_args_t *) arg;
+
+ buffer = rw_args->buffer;
+ maximum = rw_args->count;
+
+ for (count = 0; count < maximum; count++) {
+ if ( buffer[ count ] == '\n') {
+ outbyte('\r');
+ }
+ outbyte( buffer[ count ] );
+ }
+ return maximum;
+}
+
+/*
+ * IO Control entry point
+ */
+
+rtems_device_driver console_control(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+ return RTEMS_SUCCESSFUL;
+}
+
diff --git a/c/src/lib/libcpu/powerpc/ppc403/timer/timer.c b/c/src/lib/libcpu/powerpc/ppc403/timer/timer.c
new file mode 100644
index 0000000000..4d2f4c0fd4
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/ppc403/timer/timer.c
@@ -0,0 +1,98 @@
+/* timer.c
+ *
+ * This file manages the interval timer on the PowerPC 403*.
+ * We shall use the bottom 32 bits of the timebase register,
+ *
+ * NOTE: It is important that the timer start/stop overhead be
+ * determined when porting or modifying this code.
+ *
+ * Author: Andrew Bray <andy@i-cubed.co.uk>
+ *
+ * COPYRIGHT (c) 1995 by i-cubed ltd.
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of i-cubed limited not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * i-cubed limited makes no representations about the suitability
+ * of this software for any purpose.
+ *
+ * Derived from c/src/lib/libcpu/hppa1_1/timer/timer.c:
+ *
+ * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ * On-Line Applications Research Corporation (OAR).
+ * All rights assigned to U.S. Government, 1994.
+ *
+ * This material may be reproduced by or for the U.S. Government pursuant
+ * to the copyright license under the clause at DFARS 252.227-7013. This
+ * notice must appear in all copies of this file and its derivatives.
+ *
+ * $Id$
+ */
+
+#include <bsp.h>
+#include <rtems.h>
+
+extern rtems_cpu_table Cpu_table; /* owned by BSP */
+
+static volatile rtems_unsigned32 Timer_starting;
+static rtems_boolean Timer_driver_Find_average_overhead;
+
+/*
+ * This is so small that this code will be reproduced where needed.
+ */
+static INLINE rtems_unsigned32 get_itimer(void)
+{
+ rtems_unsigned32 ret;
+
+ asm volatile ("mfspr %0, 0x3dd" : "=r" ((ret))); /* TBLO */
+
+ return ret;
+}
+
+void Timer_initialize()
+{
+ rtems_unsigned32 iocr;
+
+ asm volatile ("mfdcr %0, 0xa0" : "=r" (iocr)); /* IOCR */
+ iocr &= ~4;
+ iocr |= 4; /* Select external timer clock */
+ asm volatile ("mtdcr 0xa0, %0" : "=r" (iocr) : "0" (iocr)); /* IOCR */
+
+ Timer_starting = get_itimer();
+}
+
+int Read_timer()
+{
+ rtems_unsigned32 clicks;
+ rtems_unsigned32 total;
+
+ clicks = get_itimer();
+
+ total = clicks - Timer_starting;
+
+ if ( Timer_driver_Find_average_overhead == 1 )
+ return total; /* in XXX microsecond units */
+
+ else {
+ if ( total < Cpu_table.timer_least_valid )
+ return 0; /* below timer resolution */
+ return (total - Cpu_table.timer_average_overhead);
+ }
+}
+
+rtems_status_code Empty_function( void )
+{
+ return RTEMS_SUCCESSFUL;
+}
+
+void Set_find_average_overhead(
+ rtems_boolean find_flag
+)
+{
+ Timer_driver_Find_average_overhead = find_flag;
+}
diff --git a/c/src/lib/libcpu/powerpc/ppc403/vectors/README b/c/src/lib/libcpu/powerpc/ppc403/vectors/README
new file mode 100644
index 0000000000..4081ae2525
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/ppc403/vectors/README
@@ -0,0 +1,25 @@
+#
+# $Id$
+#
+
+The location of the vectors file object is critical.
+
+From the comments at the head of vectors.s:
+
+ The issue with this file is getting it loaded at the right place.
+ The first vector MUST be at address 0x????0100.
+ How this is achieved is dependant on the tool chain.
+
+ However the basic mechanism for ELF assemblers is to create a
+ section called ".vectors", which will be loaded to an address
+ between 0x????0000 and 0x????0100 (inclusive) via a link script.
+
+ The basic mechanism for XCOFF assemblers is to place it in the
+ normal text section, and arrange for this file to be located
+ at an appropriate position on the linker command line.
+
+ The variable 'PPC_VECTOR_FILE_BASE' must be defined to be the
+ offset from 0x????0000 to the first location in the file. This
+ will usually be 0x0000 or 0x0100.
+
+Andrew Bray 18/8/1995
diff --git a/c/src/lib/libcpu/powerpc/ppc403/vectors/align_h.s b/c/src/lib/libcpu/powerpc/ppc403/vectors/align_h.s
new file mode 100644
index 0000000000..00266b87e9
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/ppc403/vectors/align_h.s
@@ -0,0 +1,433 @@
+/* align_h.s 1.1 - 95/12/04
+ *
+ * This file contains the assembly code for the PowerPC 403
+ * alignment exception handler for RTEMS.
+ *
+ * Based upon IBM provided code with the following release:
+ *
+ * This source code has been made available to you by IBM on an AS-IS
+ * basis. Anyone receiving this source is licensed under IBM
+ * copyrights to use it in any way he or she deems fit, including
+ * copying it, modifying it, compiling it, and redistributing it either
+ * with or without modifications. No license under IBM patents or
+ * patent applications is to be implied by the copyright license.
+ *
+ * Any user of this software should understand that IBM cannot provide
+ * technical support for this software and will not be responsible for
+ * any consequences resulting from the use of this software.
+ *
+ * Any person who transfers this source code or any derivative work
+ * must include the IBM copyright notice, this paragraph, and the
+ * preceding two paragraphs in the transferred software.
+ *
+ * COPYRIGHT I B M CORPORATION 1995
+ * LICENSED MATERIAL - PROGRAM PROPERTY OF I B M
+ *
+ * Modifications:
+ *
+ * Author: Andrew Bray <andy@i-cubed.co.uk>
+ *
+ * COPYRIGHT (c) 1995 by i-cubed ltd.
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of i-cubed limited not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * i-cubed limited makes no representations about the suitability
+ * of this software for any purpose.
+ *
+ * $Id$
+ */
+
+#include "asm.h"
+#include "bsp.h"
+
+.set CACHE_SIZE,16 # cache line size of 32 bytes
+.set CACHE_SIZE_L2,4 # cache line size, log 2
+
+.set Open_gpr0,0
+.set Open_gpr1,4
+.set Open_gpr2,8
+.set Open_gpr3,12
+.set Open_gpr4,16
+.set Open_gpr5,20
+.set Open_gpr6,24
+.set Open_gpr7,28
+.set Open_gpr8,32
+.set Open_gpr9,36
+.set Open_gpr10,40
+.set Open_gpr11,44
+.set Open_gpr12,48
+.set Open_gpr13,52
+.set Open_gpr14,56
+.set Open_gpr15,60
+.set Open_gpr16,64
+.set Open_gpr17,68
+.set Open_gpr18,72
+.set Open_gpr19,76
+.set Open_gpr20,80
+.set Open_gpr21,84
+.set Open_gpr22,88
+.set Open_gpr23,92
+.set Open_gpr24,96
+.set Open_gpr25,100
+.set Open_gpr26,104
+.set Open_gpr27,108
+.set Open_gpr28,112
+.set Open_gpr29,116
+.set Open_gpr30,120
+.set Open_gpr31,124
+.set Open_xer,128
+.set Open_lr,132
+.set Open_ctr,136
+.set Open_cr,140
+.set Open_srr2,144
+.set Open_srr3,148
+.set Open_srr0,152
+.set Open_srr1,156
+
+
+/*
+ * This code makes several assumptions for processing efficiency
+ * * General purpose registers are continuous in the image, beginning with
+ * Open_gpr0
+ * * Hash table is highly dependent on opcodes - opcode changes *will*
+ * require rework of the instruction decode mechanism.
+ */
+
+ .text
+ .globl align_h
+
+ .align CACHE_SIZE_L2
+align_h:
+ /*-----------------------------------------------------------------------
+ * Store GPRs in Open Reg save area
+ * Set up r2 as base reg, r1 pointing to Open Reg save area
+ *----------------------------------------------------------------------*/
+ stmw r0,ALIGN_REGS(r0)
+ li r1,ALIGN_REGS
+ /*-----------------------------------------------------------------------
+ * Store special purpose registers in reg save area
+ *----------------------------------------------------------------------*/
+ mfxer r7
+ mflr r8
+ mfcr r9
+ mfctr r10
+ stw r7,Open_xer(r1)
+ stw r8,Open_lr(r1)
+ stw r9,Open_cr(r1)
+ stw r10,Open_ctr(r1)
+ mfspr r7, srr2 /* SRR 2 */
+ mfspr r8, srr3 /* SRR 3 */
+ mfspr r9, srr0 /* SRR 0 */
+ mfspr r10, srr1 /* SRR 1 */
+ stw r7,Open_srr2(r1)
+ stw r8,Open_srr3(r1)
+ stw r9,Open_srr0(r1)
+ stw r10,Open_srr1(r1)
+
+/* Set up common registers */
+ mfspr r5, dear /* DEAR: R5 is data exception address */
+ lwz r9,Open_srr0(r1) /* get faulting instruction */
+ addi r7,r9,4 /* bump instruction */
+ stw r7,Open_srr0(r1) /* restore to image */
+ lwz r9, 0(r9) /* retrieve actual instruction */
+ rlwinm r6,r9,18,25,29 /* r6 is RA * 4 field from instruction */
+ rlwinm r7,r9,6,26,31 /* r7 is primary opcode */
+ bl ref_point /* establish addressibility */
+ref_point:
+ mflr r11 /* r11 is the anchor point for ref_point */
+ addi r10, r7, -31 /* r10 = r7 - 31 */
+ rlwinm r10,r10,2,2,31 /* r10 *= 4 */
+ add r10, r10, r11 /* r10 += anchor point */
+ lwz r10, primary_jt-ref_point(r10)
+ mtlr r10
+ rlwinm r8,r9,13,25,29 /* r8 is RD * 4 */
+ la r7,Open_gpr0(r1) /* r7 is address of GPR 0 in list */
+ blr
+primary_jt:
+ .long xform
+ .long lwz
+ .long lwzu
+ .long 0
+ .long 0
+ .long stw
+ .long stwu
+ .long 0
+ .long 0
+ .long lhz
+ .long lhzu
+ .long lha
+ .long lhau
+ .long sth
+ .long sthu
+ .long lmw
+ .long stmw
+/*
+ * handlers
+ */
+/*
+ * xform instructions require an additional decode. Fortunately, a relatively
+ * simple hash step breaks the instructions out with no collisions
+ */
+xform:
+ rlwinm r7,r9,31,22,31 /* r7 is secondary opcode */
+ rlwinm r10,r7,27,5,31 /* r10 = r7 >> 5 */
+ add r10,r7,r10 /* r10 = r7 + r10 */
+ rlwinm r10,r10,2,25,29 /* r10 = (r10 & 0x1F) * 4 */
+ add r10,r10,r11 /* r10 += anchor point */
+ lwz r10, secondary_ht-ref_point(r10)
+ mtlr r10
+ la r7,Open_gpr0(r1) /* r7 is address of GPR 0 in list */
+ rlwinm r8,r9,13,25,29 /* r8 is RD * 4 */
+ blrl
+
+secondary_ht:
+ .long lhzux /* b 0 0x137 */
+ .long lhax /* b 1 0x157 */
+ .long lhaux /* b 2 0x177 */
+ .long sthx /* b 3 0x197 */
+ .long sthux /* b 4 0x1b7 */
+ .long 0 /* b 5 */
+ .long lwbrx /* b 6 0x216 */
+ .long 0 /* b 7 */
+ .long 0 /* b 8 */
+ .long 0 /* b 9 */
+ .long stwbrx /* b A 0x296 */
+ .long 0 /* b B */
+ .long 0 /* b C */
+ .long 0 /* b D */
+ .long lhbrx /* b E 0x316 */
+ .long 0 /* b F */
+ .long 0 /* b 10 */
+ .long 0 /* b 11 */
+ .long sthbrx /* b 12 0x396 */
+ .long 0 /* b 13 */
+ .long lwarx /* b 14 0x014 */
+ .long dcbz /* b 15 0x3f6 */
+ .long 0 /* b 16 */
+ .long lwzx /* b 17 0x017 */
+ .long lwzux /* b 18 0x037 */
+ .long 0 /* b 19 */
+ .long stwcx /* b 1A 0x096 */
+ .long stwx /* b 1B 0x097 */
+ .long stwux /* b 1C 0x0B7 */
+ .long 0 /* b 1D */
+ .long 0 /* b 1E */
+ .long lhzx /* b 1F 0x117 */
+
+/*
+ * for all handlers
+ * r4 - Addressability to interrupt context
+ * r5 - DEAR address (faulting data address)
+ * r6 - RA field * 4
+ * r7 - Address of GPR 0 in image
+ * r8 - RD field * 4
+ * r9 - Failing instruction
+ */
+
+/* Load halfword algebraic with update */
+lhau:
+/* Load halfword algebraic with update indexed */
+lhaux:
+ stwx r5,r7,r6 /* update RA with effective addr */
+
+/* Load halfword algebraic */
+lha:
+/* Load halfword algebraic indexed */
+lhax:
+ lswi r10,r5,2 /* load two bytes into r10 */
+ srawi r10,r10,16 /* shift right 2 bytes, extending sign */
+ stwx r10,r7,r8 /* update reg image */
+ b align_complete /* return */
+
+/* Load Half Word Byte-Reversed Indexed */
+lhbrx:
+ lswi r10,r5,2 /* load two bytes from DEAR into r10 */
+ rlwinm r10,r10,0,0,15 /* mask off lower 2 bytes */
+ stwbrx r10,r7,r8 /* store reversed in reg image */
+ b align_complete /* return */
+
+/* Load Half Word and Zero with Update */
+lhzu:
+/* Load Half Word and Zero with Update Indexed */
+lhzux:
+ stwx r5,r7,r6 /* update RA with effective addr */
+
+/* Load Half Word and Zero */
+lhz:
+/* Load Half Word and Zero Indexed */
+lhzx:
+ lswi r10,r5,2 /* load two bytes from DEAR into r10 */
+ rlwinm r10,r10,16,16,31 /* shift right 2 bytes, with zero fill */
+ stwx r10,r7,r8 /* update reg image */
+ b align_complete /* return */
+
+/*
+ * Load Multiple Word
+ */
+lmw:
+ lwzx r9,r6,r7 /* R9 contains saved value of RA */
+ addi r10,r7,32*4 /* r10 points to r31 in image + 4 */
+ rlwinm r8,r8,30,2,31 /* r8 >>= 2 (recovers RT) */
+ subfic r8,r8,32 /* r8 is reg count to load */
+ mtctr r8 /* load counter */
+ addi r8,r8,-1 /* r8-- */
+ rlwinm r8,r8,2,2,31 /* r8 *= 4 */
+ add r5,r5,r8 /* update DEAR to point to last reg */
+lwmloop:
+ lswi r11,r5,4 /* load r11 with 4 bytes from DEAR */
+ stwu r11,-4(r10) /* load image and decrement pointer */
+ addi r5,r5,-4 /* decrement effective address */
+ bdnz lwmloop
+ stwx r9,r6,r7 /* restore RA (in case it was trashed) */
+ b align_complete /* return */
+
+/*
+ * Load Word and Reserve Indexed
+ */
+lwarx:
+ lswi r10,r5,4 /* load four bytes from DEAR into r10 */
+ stwx r10,r7,r8 /* update reg image */
+ rlwinm r5,r5,0,0,29 /* Word align address */
+ lwarx r10,0,r5 /* Set reservation */
+ b align_complete /* return */
+
+/*
+ * Load Word Byte-Reversed Indexed
+ */
+lwbrx:
+ lswi r10,r5,4 /* load four bytes from DEAR into r10 */
+ stwbrx r10,r7,r8 /* store reversed in reg image */
+ b align_complete /* return */
+
+/* Load Word and Zero with Update */
+lwzu:
+/* Load Word and Zero with Update Indexed */
+lwzux:
+ stwx r5,r7,r6 /* update RA with effective addr */
+
+/* Load Word and Zero */
+lwz:
+/* Load Word and Zero Indexed */
+lwzx:
+ lswi r10,r5,4 /* load four bytes from DEAR into r10 */
+ stwx r10,r7,r8 /* update reg image */
+ b align_complete /* return */
+
+/* Store instructions */
+
+/* */
+/* Store Half Word and Update */
+sthu:
+/* Store Half Word and Update Indexed */
+sthux:
+ stwx r5,r7,r6 /* Update RA with effective address */
+
+/* Store Half Word */
+sth:
+/* Store Half Word Indexed */
+sthx:
+ lwzx r10,r8,r7 /* retrieve source register value */
+ rlwinm r10,r10,16,0,15 /* move two bytes to high end of reg */
+ stswi r10,r5,2 /* store bytes to DEAR address */
+ b align_complete /* return */
+
+/* */
+/* Store Half Word Byte-Reversed Indexed */
+sthbrx:
+ lwbrx r10,r8,r7 /* retrieve src reg value byte reversed */
+ stswi r10,r5,2 /* move two bytes to DEAR address */
+ b align_complete /* return */
+
+/* */
+/* Store Multiple Word */
+stmw:
+ addi r10,r7,32*4 /* r10 points to r31 in image + 4 */
+ rlwinm r8,r8,30,2,31 /* r8 >>= 2 (recovers RT) */
+ subfic r8,r8,32 /* r8 is reg count to load */
+ mtctr r8 /* load counter */
+ addi r8,r8,-1 /* r8-- */
+ rlwinm r8,r8,2,2,31 /* r8 *= 4 */
+ add r5,r5,r8 /* update DEAR to point to last reg */
+stmloop:
+ lwzu r11,-4(r10) /* get register value */
+ stswi r11,r5,4 /* output to DEAR address */
+ addi r5,r5,-4 /* decrement effective address */
+ bdnz stmloop
+ b align_complete /* return */
+
+/* */
+/* Store Word and Update */
+stwu:
+/* Store Word and Update Indexed */
+stwux:
+ stwx r5,r7,r6 /* Update RA with effective address */
+
+/* Store Word */
+stw:
+/* Store Word Indexed */
+stwx:
+ lwzx r10,r8,r7 /* retrieve source register value */
+ stswi r10,r5,4 /* store bytes to DEAR address */
+ b align_complete /* return */
+
+/* */
+/* Store Word Byte-Reversed Indexed */
+stwbrx:
+ lwbrx r10,r8,r7 /* retrieve src reg value byte reversed */
+ stswi r10,r5,4 /* move two bytes to DEAR address */
+ b align_complete /* return */
+
+/* */
+/* Store Word Conditional Indexed */
+stwcx:
+ rlwinm r10,r5,0,0,29 /* r10 = word aligned DEAR */
+ lwz r11,0(r10) /* save original value of store */
+ stwcx. r11,r0,r10 /* attempt store to address */
+ bne stwcx_moveon /* store failed, move on */
+ stw r11,0(r10) /* repair damage */
+ lwzx r9,r7,r8 /* get register value */
+ stswi r10,r5,4 /* store bytes to DEAR address */
+stwcx_moveon:
+ mfcr r11 /* get condition reg */
+ lwz r9,Open_cr(r1) /* get condition reg image */
+ rlwimi r9,r11,0,0,2 /* insert 3 CR bits into cr image */
+ lwz r11,Open_xer(r1) /* get XER reg */
+ rlwimi r9,r11,29,2,2 /* insert XER SO bit into cr image */
+ stw r9,Open_cr(r1) /* store cr image */
+ b align_complete /* return */
+
+/* */
+/* Data Cache Block Zero */
+dcbz:
+ rlwinm r5,r5,0,0,31-CACHE_SIZE_L2
+ /* get address to nearest Cache line */
+ addi r5,r5,-4 /* adjust by a word */
+ addi r10,r0,CACHE_SIZE/4 /* set counter value */
+ mtctr r10
+ addi r11,r0,0 /* r11 = 0 */
+dcbz_loop:
+ stwu r11,4(r5) /* store a word and update EA */
+ bdnz dcbz_loop
+ b align_complete /* return */
+
+align_complete:
+ /*-----------------------------------------------------------------------
+ * Restore regs and return from the interrupt
+ *----------------------------------------------------------------------*/
+ lmw r24,Open_xer+ALIGN_REGS(r0)
+ mtxer r24
+ mtlr r25
+ mtctr r26
+ mtcrf 0xFF, r27
+ mtspr srr2, r28 /* SRR 2 */
+ mtspr srr3, r29 /* SRR 3 */
+ mtspr srr0, r30 /* SRR 0 */
+ mtspr srr1, r31 /* SRR 1 */
+ lmw r0,Open_gpr0+ALIGN_REGS(r0)
+ rfi
diff --git a/c/src/lib/libcpu/powerpc/ppc403/vectors/vectors.s b/c/src/lib/libcpu/powerpc/ppc403/vectors/vectors.s
new file mode 100644
index 0000000000..b764207648
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/ppc403/vectors/vectors.s
@@ -0,0 +1,282 @@
+/* vectors.s 1.1 - 95/12/04
+ *
+ * This file contains the assembly code for the PowerPC 403
+ * interrupt veneers for RTEMS.
+ *
+ * Author: Andrew Bray <andy@i-cubed.co.uk>
+ *
+ * COPYRIGHT (c) 1995 by i-cubed ltd.
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of i-cubed limited not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * i-cubed limited makes no representations about the suitability
+ * of this software for any purpose.
+ *
+ */
+
+/*
+ * The issue with this file is getting it loaded at the right place.
+ * The first vector MUST be at address 0x????0100.
+ * How this is achieved is dependant on the tool chain.
+ *
+ * However the basic mechanism for ELF assemblers is to create a
+ * section called ".vectors", which will be loaded to an address
+ * between 0x????0000 and 0x????0100 (inclusive) via a link script.
+ *
+ * The basic mechanism for XCOFF assemblers is to place it in the
+ * normal text section, and arrange for this file to be located
+ * at an appropriate position on the linker command line.
+ *
+ * The variable 'PPC_VECTOR_FILE_BASE' must be defined to be the
+ * offset from 0x????0000 to the first location in the file. This
+ * will usually be 0x0000 or 0x0100.
+ *
+ * $Id$
+ */
+
+#include "asm.h"
+
+#ifndef PPC_VECTOR_FILE_BASE
+#error "PPC_VECTOR_FILE_BASE is not defined."
+#endif
+
+ /* Where this file will be loaded */
+ .set file_base, PPC_VECTOR_FILE_BASE
+
+ /* Offset to store reg 0 */
+
+ .set IP_LINK, 0
+#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
+ .set IP_0, (IP_LINK + 56)
+#else
+ .set IP_0, (IP_LINK + 8)
+#endif
+ .set IP_2, (IP_0 + 4)
+
+ .set IP_3, (IP_2 + 4)
+ .set IP_4, (IP_3 + 4)
+ .set IP_5, (IP_4 + 4)
+ .set IP_6, (IP_5 + 4)
+
+ .set IP_7, (IP_6 + 4)
+ .set IP_8, (IP_7 + 4)
+ .set IP_9, (IP_8 + 4)
+ .set IP_10, (IP_9 + 4)
+
+ .set IP_11, (IP_10 + 4)
+ .set IP_12, (IP_11 + 4)
+ .set IP_13, (IP_12 + 4)
+ .set IP_28, (IP_13 + 4)
+
+ .set IP_29, (IP_28 + 4)
+ .set IP_30, (IP_29 + 4)
+ .set IP_31, (IP_30 + 4)
+ .set IP_CR, (IP_31 + 4)
+
+ .set IP_CTR, (IP_CR + 4)
+ .set IP_XER, (IP_CTR + 4)
+ .set IP_LR, (IP_XER + 4)
+ .set IP_PC, (IP_LR + 4)
+
+ .set IP_MSR, (IP_PC + 4)
+
+ .set IP_END, (IP_MSR + 16)
+
+ /* Vector offsets */
+ .set begin_vector,0x0000
+ .set crit_vector,0x0100
+ .set mach_vector,0x0200
+ .set prot_vector,0x0300
+ .set ext_vector,0x0500
+ .set align_vector,0x0600
+ .set prog_vector,0x0700
+ .set sys_vector,0x0C00
+ .set pit_vector,0x1000
+ .set fit_vector,0x1010
+ .set wadt_vector,0x1020
+ .set debug_vector,0x2000
+
+/* Go to the right section */
+#if PPC_ASM == PPC_ASM_ELF
+ .section .vectors,"awx",@progbits
+#elif PPC_ASM == PPC_ASM_XCOFF
+ .csect .text[PR]
+#endif
+
+ PUBLIC_VAR (__vectors)
+SYM (__vectors):
+
+/* Critical error handling */
+ .org crit_vector - file_base
+#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
+#if (PPC_HAS_FPU)
+ stwu r1, -(20*4 + 18*8 + IP_END)(r1)
+#else
+ stwu r1, -(20*4 + IP_END)(r1)
+#endif
+#else
+ stwu r1, -(IP_END)(r1)
+#endif
+ stw r0, IP_0(r1)
+
+ li r0, PPC_IRQ_CRIT
+ b PROC (_ISR_HandlerC)
+
+/* Machine check exception */
+ .org mach_vector - file_base
+#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
+#if (PPC_HAS_FPU)
+ stwu r1, -(20*4 + 18*8 + IP_END)(r1)
+#else
+ stwu r1, -(20*4 + IP_END)(r1)
+#endif
+#else
+ stwu r1, -(IP_END)(r1)
+#endif
+ stw r0, IP_0(r1)
+
+ li r0, PPC_IRQ_MCHECK
+ b PROC (_ISR_HandlerC)
+
+/* Protection exception */
+ .org prot_vector - file_base
+#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
+#if (PPC_HAS_FPU)
+ stwu r1, -(20*4 + 18*8 + IP_END)(r1)
+#else
+ stwu r1, -(20*4 + IP_END)(r1)
+#endif
+#else
+ stwu r1, -(IP_END)(r1)
+#endif
+ stw r0, IP_0(r1)
+
+ li r0, PPC_IRQ_PROTECT
+ b PROC (_ISR_Handler)
+
+/* External interrupt */
+ .org ext_vector - file_base
+#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
+#if (PPC_HAS_FPU)
+ stwu r1, -(20*4 + 18*8 + IP_END)(r1)
+#else
+ stwu r1, -(20*4 + IP_END)(r1)
+#endif
+#else
+ stwu r1, -(IP_END)(r1)
+#endif
+ stw r0, IP_0(r1)
+
+ li r0, PPC_IRQ_EXTERNAL
+ b PROC (_ISR_Handler)
+
+/* Align exception */
+ .org align_vector - file_base
+ .extern align_h
+ b align_h
+
+/* Program exception */
+ .org prog_vector - file_base
+#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
+#if (PPC_HAS_FPU)
+ stwu r1, -(20*4 + 18*8 + IP_END)(r1)
+#else
+ stwu r1, -(20*4 + IP_END)(r1)
+#endif
+#else
+ stwu r1, -(IP_END)(r1)
+#endif
+ stw r0, IP_0(r1)
+
+ li r0, PPC_IRQ_PROGRAM
+ b PROC (_ISR_Handler)
+
+/* System call */
+ .org sys_vector - file_base
+#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
+#if (PPC_HAS_FPU)
+ stwu r1, -(20*4 + 18*8 + IP_END)(r1)
+#else
+ stwu r1, -(20*4 + IP_END)(r1)
+#endif
+#else
+ stwu r1, -(IP_END)(r1)
+#endif
+ stw r0, IP_0(r1)
+
+ li r0, PPC_IRQ_SCALL
+ b PROC (_ISR_Handler)
+
+/* PIT interrupt */
+ .org pit_vector - file_base
+#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
+#if (PPC_HAS_FPU)
+ stwu r1, -(20*4 + 18*8 + IP_END)(r1)
+#else
+ stwu r1, -(20*4 + IP_END)(r1)
+#endif
+#else
+ stwu r1, -(IP_END)(r1)
+#endif
+ stw r0, IP_0(r1)
+
+ li r0, PPC_IRQ_PIT
+ b PROC (_ISR_Handler)
+
+/* FIT interrupt */
+ .org fit_vector - file_base
+#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
+#if (PPC_HAS_FPU)
+ stwu r1, -(20*4 + 18*8 + IP_END)(r1)
+#else
+ stwu r1, -(20*4 + IP_END)(r1)
+#endif
+#else
+ stwu r1, -(IP_END)(r1)
+#endif
+ stw r0, IP_0(r1)
+
+ li r0, PPC_IRQ_FIT
+ b PROC (_ISR_Handler)
+
+/* Watchdog interrupt */
+ .org wadt_vector - file_base
+#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
+#if (PPC_HAS_FPU)
+ stwu r1, -(20*4 + 18*8 + IP_END)(r1)
+#else
+ stwu r1, -(20*4 + IP_END)(r1)
+#endif
+#else
+ stwu r1, -(IP_END)(r1)
+#endif
+ stw r0, IP_0(r1)
+
+ li r0, PPC_IRQ_WATCHDOG
+ b PROC (_ISR_HandlerC)
+
+/* Debug exception */
+debug:
+#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
+#if (PPC_HAS_FPU)
+ stwu r1, -(20*4 + 18*8 + IP_END)(r1)
+#else
+ stwu r1, -(20*4 + IP_END)(r1)
+#endif
+#else
+ stwu r1, -(IP_END)(r1)
+#endif
+ stw r0, IP_0(r1)
+
+ li r0, PPC_IRQ_DEBUG
+ b PROC (_ISR_HandlerC)
+
+/* Debug exception */
+ .org debug_vector - file_base
+ b debug