diff options
Diffstat (limited to '')
-rw-r--r-- | c/src/lib/libc/__brk.c | 2 | ||||
-rw-r--r-- | c/src/lib/libc/__gettod.c | 2 | ||||
-rw-r--r-- | c/src/lib/libc/newlibc.c | 2 | ||||
-rw-r--r-- | c/src/lib/libcpu/powerpc/README | 9 | ||||
-rw-r--r-- | c/src/lib/libcpu/powerpc/ppc403/README | 18 | ||||
-rw-r--r-- | c/src/lib/libcpu/powerpc/ppc403/clock/clock.c | 215 | ||||
-rw-r--r-- | c/src/lib/libcpu/powerpc/ppc403/console/console.c | 327 | ||||
-rw-r--r-- | c/src/lib/libcpu/powerpc/ppc403/timer/timer.c | 98 | ||||
-rw-r--r-- | c/src/lib/libcpu/powerpc/ppc403/vectors/README | 21 | ||||
-rw-r--r-- | c/src/lib/libcpu/powerpc/ppc403/vectors/vectors.s | 332 |
10 files changed, 1023 insertions, 3 deletions
diff --git a/c/src/lib/libc/__brk.c b/c/src/lib/libc/__brk.c index 7c43ffa32b..5f256cb072 100644 --- a/c/src/lib/libc/__brk.c +++ b/c/src/lib/libc/__brk.c @@ -14,7 +14,7 @@ * 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. * - * __brk.c,v 1.2 1995/05/09 20:24:28 joel Exp + * $Id$ */ #include <rtems.h> diff --git a/c/src/lib/libc/__gettod.c b/c/src/lib/libc/__gettod.c index 6f8df8a65f..d01a85b4a4 100644 --- a/c/src/lib/libc/__gettod.c +++ b/c/src/lib/libc/__gettod.c @@ -11,7 +11,7 @@ * 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. * - * __gettod.c,v 1.2 1995/05/09 20:24:31 joel Exp + * $Id$ */ #include <rtems.h> diff --git a/c/src/lib/libc/newlibc.c b/c/src/lib/libc/newlibc.c index c3e886266d..4493b473da 100644 --- a/c/src/lib/libc/newlibc.c +++ b/c/src/lib/libc/newlibc.c @@ -35,7 +35,7 @@ * * NOTE: * - * newlibc.c,v 1.2 1995/05/09 20:24:37 joel Exp + * $Id$ * */ diff --git a/c/src/lib/libcpu/powerpc/README b/c/src/lib/libcpu/powerpc/README new file mode 100644 index 0000000000..861c3e2df6 --- /dev/null +++ b/c/src/lib/libcpu/powerpc/README @@ -0,0 +1,9 @@ +This hierachy contains support routines for the various +PowerPC processors. + +Since these routines can differ amongst different members +of the PowerPC family, an entry per CPU type is provided. + +Currently only the PPC403 is supported. + +Andrew Bray 18/8/1995 diff --git a/c/src/lib/libcpu/powerpc/ppc403/README b/c/src/lib/libcpu/powerpc/ppc403/README new file mode 100644 index 0000000000..f99e0533f7 --- /dev/null +++ b/c/src/lib/libcpu/powerpc/ppc403/README @@ -0,0 +1,18 @@ +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 memebers 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 + handlres: 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..fc17de4cc8 --- /dev/null +++ b/c/src/lib/libcpu/powerpc/ppc403/clock/clock.c @@ -0,0 +1,215 @@ +/* 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.demon.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. + * + * clock.c,v 1.2 1995/05/31 16:59:06 joel Exp + */ + +#include <bsp.h> +#include <clockdrv.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; + +rtems_device_driver Clock_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *pargp, + rtems_id tid, + rtems_unsigned32 *rval +) +{ + Install_clock(Clock_isr); +} + + +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); +} + +static INLINE rtems_unsigned32 get_itimer(void) +{ + register rtems_unsigned32 rc; + + asm volatile ("mftblo %0" : "=r" ((rc))); + + return rc; +} + +void Install_clock(rtems_isr_entry clock_isr) +{ + rtems_isr_entry previous_isr; + rtems_unsigned32 pvr, iocr; + + Clock_driver_ticks = 0; + + asm volatile ("mfiocr %0" : "=r" (iocr)); + iocr &= ~4; + iocr |= 4; /* Select external timer clock */ + asm volatile ("mtiocr %0" : "=r" (iocr) : "0" (iocr)); + + asm volatile ("mfpvr %0" : "=r" ((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 ("mtpit %0" : : "r" (pit_value)); + + asm volatile ("mftcr %0" : "=r" ((tcr))); + + tcr &= ~ 0x04400000; + + tcr |= (auto_restart ? 0x04400000 : 0x04000000); + + tick_time = get_itimer() + pit_value; + + asm volatile ("mttcr %0" : "=r" ((tcr)) : "0" ((tcr))); + } + atexit(Clock_exit); +} + + +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 ("mtpit %0" :: "r" (clicks_til_next_interrupt)); + } + + asm volatile ( "mttsr %0" :: "r" (0x08000000)); + + Clock_driver_ticks++; + + rtems_clock_tick(); +} + +/* + * 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 ("mftcr %0" : "=r" ((tcr))); + + tcr &= ~ 0x04400000; + + asm volatile ("mttcr %0" : "=r" ((tcr)) : "0" ((tcr))); + + (void) set_vector(0, PPC_IRQ_PIT, 1); + } +} + 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..6a451bb7ec --- /dev/null +++ b/c/src/lib/libcpu/powerpc/ppc403/console/console.c @@ -0,0 +1,327 @@ +/* + * This file contains the PowerPC 403GA console IO package. + * + * Author: Andrew Bray <andy@i-cubed.demon.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. + * + * console.c,v 1.2 1995/05/31 16:56:07 joel Exp + */ + +#define NO_BSP_INIT + +#include <rtems.h> +#include "console.h" +#include "bsp.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_id self, + rtems_unsigned32 *status +) +{ + register unsigned tmp; + + /* Initialise the serial port */ + asm volatile ("mfiocr %0" : "=r" (tmp)); + tmp &= ~3; + tmp |= (Cpu_table.serial_external_clock ? 2 : 0) | + (Cpu_table.serial_cts_rts ? 1 : 0); + asm volatile ("mtiocr %0" : "=r" (tmp) : "0" (tmp)); + 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_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; +} + +/* + * __read -- read bytes from the serial port. Ignore fd, since + * we only have stdin. + */ + +int __read( + int fd, + char *buf, + int nbytes +) +{ + int i = 0; + + for (i = 0; i < nbytes; i++) { + *(buf + i) = inbyte(); + if ((*(buf + i) == '\n') || (*(buf + i) == '\r')) { + (*(buf + i++)) = '\n'; + (*(buf + i)) = 0; + break; + } + } + return (i); +} + +/* + * __write -- write bytes to the serial port. Ignore fd, since + * stdout and stderr are the same. Since we have no filesystem, + * open will only return an error. + */ + +int __write( + int fd, + char *buf, + int nbytes +) +{ + int i; + + for (i = 0; i < nbytes; i++) { + if (*(buf + i) == '\n') { + outbyte ('\r'); + } + outbyte (*(buf + i)); + } + return (nbytes); +} 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..f351a9109d --- /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.demon.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. + * + * timer.c,v 1.2 1995/05/31 16:59:23 joel Exp + */ + +#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 ("mftblo %0" : "=r" ((ret))); + + return ret; +} + +void Timer_initialize() +{ + rtems_unsigned32 iocr; + + asm volatile ("mfiocr %0" : "=r" (iocr)); + iocr &= ~4; + iocr |= 4; /* Select external timer clock */ + asm volatile ("mtiocr %0" : "=r" (iocr) : "0" (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..02ab163dfd --- /dev/null +++ b/c/src/lib/libcpu/powerpc/ppc403/vectors/README @@ -0,0 +1,21 @@ +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/vectors.s b/c/src/lib/libcpu/powerpc/ppc403/vectors/vectors.s new file mode 100644 index 0000000000..ea08a5156d --- /dev/null +++ b/c/src/lib/libcpu/powerpc/ppc403/vectors/vectors.s @@ -0,0 +1,332 @@ +/* vectors.s 1.0 - 95/08/08 + * + * This file contains the assembly code for the PowerPC 403 + * interrupt veneers for RTEMS. + * + * Author: Andrew Bray <andy@i-cubed.demon.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. + */ + +#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 + mtsprg1 r0 + mfsprg2 r0 + mtmsr r0 +#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 + mfsprg1 r0 + stw r0, IP_0(r1) + + li r0, PPC_IRQ_CRIT + b PROC (_ISR_HandlerC) + +/* Machine check exception */ + .org mach_vector - file_base + mtsprg1 r0 + mfsprg2 r0 + mtmsr r0 +#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 + mfsprg1 r0 + stw r0, IP_0(r1) + + li r0, PPC_IRQ_MCHECK + b PROC (_ISR_HandlerC) + +/* Protection exception */ + .org prot_vector - file_base + mtsprg0 r0 + mfsprg2 r0 + mtmsr r0 +#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 + mfsprg0 r0 + stw r0, IP_0(r1) + + li r0, PPC_IRQ_PROTECT + b PROC (_ISR_Handler) + +/* External interrupt */ + .org ext_vector - file_base + mtsprg0 r0 + mfsprg2 r0 + mtmsr r0 +#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 + mfsprg0 r0 + 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 + mtsprg0 r0 + mfsprg2 r0 + mtmsr r0 +#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 + mfsprg0 r0 + stw r0, IP_0(r1) + + li r0, PPC_IRQ_PROGRAM + b PROC (_ISR_Handler) + +/* System call */ + .org sys_vector - file_base + mtsprg0 r0 + mfsprg2 r0 + mtmsr r0 +#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 + mfsprg0 r0 + stw r0, IP_0(r1) + + li r0, PPC_IRQ_SCALL + b PROC (_ISR_Handler) + +/* PIT interrupt */ + .org pit_vector - file_base + b pit + +/* FIT interrupt */ + .org fit_vector - file_base + b fit + +/* Watchdog interrupt */ + .org wadt_vector - file_base + b watch + +/* PIT interrupt */ +pit: + mtsprg0 r0 + mfsprg2 r0 + mtmsr r0 +#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 + mfsprg0 r0 + stw r0, IP_0(r1) + + li r0, PPC_IRQ_PIT + b PROC (_ISR_Handler) + +/* FIT interrupt */ +fit: + mtsprg0 r0 + mfsprg2 r0 + mtmsr r0 +#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 + mfsprg0 r0 + stw r0, IP_0(r1) + + li r0, PPC_IRQ_FIT + b PROC (_ISR_Handler) + +/* Watchdog interrupt */ +watch: + mtsprg1 r0 + mfsprg2 r0 + mtmsr r0 +#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 + mfsprg1 r0 + stw r0, IP_0(r1) + + li r0, PPC_IRQ_WATCHDOG + b PROC (_ISR_HandlerC) + +/* Debug exception */ +debug: + mtsprg1 r0 + mfsprg2 r0 + mtmsr r0 +#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 + mfsprg1 r0 + stw r0, IP_0(r1) + + li r0, PPC_IRQ_DEBUG + b PROC (_ISR_HandlerC) + +/* Debug exception */ + .org debug_vector - file_base + b debug |