From 486c329f2b4f95dbfefdcbefbe6b25adf7895a94 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Wed, 20 Sep 1995 15:05:19 +0000 Subject: Actually adding efi bsp's from John Gwynne after forgetting to commit them. --- c/src/lib/libbsp/m68k/efi332/README | 42 ++ c/src/lib/libbsp/m68k/efi332/clock/ckinit.c | 145 ++++ c/src/lib/libbsp/m68k/efi332/console/console.c | 390 +++++++++++ c/src/lib/libbsp/m68k/efi332/include/bsp.h | 147 ++++ c/src/lib/libbsp/m68k/efi332/include/coverhd.h | 106 +++ c/src/lib/libbsp/m68k/efi332/include/efi332.h | 46 ++ c/src/lib/libbsp/m68k/efi332/spurious/spinit.c | 85 +++ c/src/lib/libbsp/m68k/efi332/startup/bspclean.c | 28 + c/src/lib/libbsp/m68k/efi332/startup/bspstart.c | 220 ++++++ c/src/lib/libbsp/m68k/efi332/startup/linkcmds | 100 +++ c/src/lib/libbsp/m68k/efi332/timer/timer.c | 84 +++ c/src/lib/libbsp/m68k/efi68k/README | 48 ++ c/src/lib/libbsp/m68k/efi68k/clock/ckinit.c | 165 +++++ c/src/lib/libbsp/m68k/efi68k/console/console.c | 363 ++++++++++ c/src/lib/libbsp/m68k/efi68k/include/16550.h | 120 ++++ c/src/lib/libbsp/m68k/efi68k/include/DP8570A.h | 285 ++++++++ c/src/lib/libbsp/m68k/efi68k/include/bsp.h | 153 +++++ c/src/lib/libbsp/m68k/efi68k/include/coverhd.h | 106 +++ c/src/lib/libbsp/m68k/efi68k/include/efi68k.h | 21 + c/src/lib/libbsp/m68k/efi68k/spurious/spinit.c | 85 +++ c/src/lib/libbsp/m68k/efi68k/startup/bspclean.c | 28 + c/src/lib/libbsp/m68k/efi68k/startup/bspstart.c | 230 +++++++ c/src/lib/libbsp/m68k/efi68k/startup/efi68k_tcp.c | 248 +++++++ c/src/lib/libbsp/m68k/efi68k/startup/efi68k_wd.c | 55 ++ c/src/lib/libbsp/m68k/efi68k/startup/linkcmds | 108 +++ c/src/lib/libbsp/m68k/efi68k/startup/m68k-stub.c | 782 ++++++++++++++++++++++ c/src/lib/libbsp/m68k/efi68k/startup/setvec.c | 45 ++ c/src/lib/libbsp/m68k/efi68k/timer/timer.c | 141 ++++ 28 files changed, 4376 insertions(+) create mode 100644 c/src/lib/libbsp/m68k/efi332/README create mode 100644 c/src/lib/libbsp/m68k/efi332/clock/ckinit.c create mode 100644 c/src/lib/libbsp/m68k/efi332/console/console.c create mode 100644 c/src/lib/libbsp/m68k/efi332/include/bsp.h create mode 100644 c/src/lib/libbsp/m68k/efi332/include/coverhd.h create mode 100644 c/src/lib/libbsp/m68k/efi332/include/efi332.h create mode 100644 c/src/lib/libbsp/m68k/efi332/spurious/spinit.c create mode 100644 c/src/lib/libbsp/m68k/efi332/startup/bspclean.c create mode 100644 c/src/lib/libbsp/m68k/efi332/startup/bspstart.c create mode 100644 c/src/lib/libbsp/m68k/efi332/startup/linkcmds create mode 100644 c/src/lib/libbsp/m68k/efi332/timer/timer.c create mode 100644 c/src/lib/libbsp/m68k/efi68k/README create mode 100644 c/src/lib/libbsp/m68k/efi68k/clock/ckinit.c create mode 100644 c/src/lib/libbsp/m68k/efi68k/console/console.c create mode 100644 c/src/lib/libbsp/m68k/efi68k/include/16550.h create mode 100644 c/src/lib/libbsp/m68k/efi68k/include/DP8570A.h create mode 100644 c/src/lib/libbsp/m68k/efi68k/include/bsp.h create mode 100644 c/src/lib/libbsp/m68k/efi68k/include/coverhd.h create mode 100644 c/src/lib/libbsp/m68k/efi68k/include/efi68k.h create mode 100644 c/src/lib/libbsp/m68k/efi68k/spurious/spinit.c create mode 100644 c/src/lib/libbsp/m68k/efi68k/startup/bspclean.c create mode 100644 c/src/lib/libbsp/m68k/efi68k/startup/bspstart.c create mode 100644 c/src/lib/libbsp/m68k/efi68k/startup/efi68k_tcp.c create mode 100644 c/src/lib/libbsp/m68k/efi68k/startup/efi68k_wd.c create mode 100644 c/src/lib/libbsp/m68k/efi68k/startup/linkcmds create mode 100644 c/src/lib/libbsp/m68k/efi68k/startup/m68k-stub.c create mode 100644 c/src/lib/libbsp/m68k/efi68k/startup/setvec.c create mode 100644 c/src/lib/libbsp/m68k/efi68k/timer/timer.c (limited to 'c') diff --git a/c/src/lib/libbsp/m68k/efi332/README b/c/src/lib/libbsp/m68k/efi332/README new file mode 100644 index 0000000000..12d8cc13cf --- /dev/null +++ b/c/src/lib/libbsp/m68k/efi332/README @@ -0,0 +1,42 @@ +# +# $Id$ +# + +Description: efi68k +============ +CPU: MC68332 @16MHz +RAM: 256k max. (supports several configurations) +ROM: 512k (supports several configurations) + + This general purpose controller has been designed by a group of +Internet subscribes to the mailing list "efi332" (an offshoot of the +"diy_efi" mailing list). Although efi332 was initially designed for +automotive research, it is a fairly generalized embedded controller +when used without the companion EFI board. It is patterned much after +the the Motorola BCC but cost on the order of $250US. A 4x3 inch +(approx.) printed circuit board is available. For complete +information see + + http://www.cim.swin.edu.au/wwwhome/aden/efi332/332_index.html + +TODO: +===== +- add separate interrupt stack (low priority). + +- add a timer driver for the tmtest set. + +- generate include/coverhd.c to preform the tmtest. + +- the interrupt drive I/O should be integrated into the RTEMS. + +- finish the ROM memory model. + + + John S Gwynne + Gwynne.1@osu.edu +_______________________________________________________________________________ + T h e O h i o - S t a t e U n i v e r s i t y + ElectroScience Laboratory, 1320 Kinnear Road, Columbus, Ohio 43212, USA + Telephone: (614) 292-7981 * Fax: (614) 292-7297 +------------------------------------------------------------------------------- + diff --git a/c/src/lib/libbsp/m68k/efi332/clock/ckinit.c b/c/src/lib/libbsp/m68k/efi332/clock/ckinit.c new file mode 100644 index 0000000000..2bfa34d32d --- /dev/null +++ b/c/src/lib/libbsp/m68k/efi332/clock/ckinit.c @@ -0,0 +1,145 @@ +/* Clock_init() + * + * This routine initailizes the periodic interrupt timer on + * the Motorola 68332. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * 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 +#include +#include +#include + +#define CLOCK_VECTOR EFI_PIV + +rtems_unsigned32 Clock_isrs; /* ISRs until next tick */ +volatile rtems_unsigned32 Clock_driver_ticks; + /* ticks since initialization */ +rtems_isr_entry Old_ticker; + +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; + +rtems_isr Clock_isr(rtems_vector_number vector) +{ + Clock_driver_ticks += 1; + + if ( Clock_isrs == 1 ) { + rtems_clock_tick(); + Clock_isrs = BSP_Configuration.microseconds_per_tick / 1000; + } + else + Clock_isrs -= 1; +} + +void Install_clock( + rtems_isr_entry clock_isr +) +{ + Clock_driver_ticks = 0; + Clock_isrs = BSP_Configuration.microseconds_per_tick / 1000; + + if ( BSP_Configuration.ticks_per_timeslice ) { + Old_ticker = (rtems_isr_entry) set_vector( clock_isr, CLOCK_VECTOR, 1 ); + + /* enable 1mS interrupts */ + *PITR = (unsigned short int)( SAM(0x09,0,PITM) );/* load counter */ + *PICR = (unsigned short int) /* enable interrupt */ + ( SAM(ISRL_PIT,8,PIRQL) | SAM(CLOCK_VECTOR,0,PIV) ); + + atexit( Clock_exit ); + } +} + +void ReInstall_clock( + rtems_isr_entry clock_isr +) +{ + rtems_unsigned32 isrlevel = 0 ; + + rtems_interrupt_disable( isrlevel ); + (void) set_vector( clock_isr, CLOCK_VECTOR, 1 ); + rtems_interrupt_enable( isrlevel ); +} + +void Clock_exit( void ) +{ + + if ( BSP_Configuration.ticks_per_timeslice ) { + + /* shutdown the periodic interrupt */ + *PICR = (unsigned short int) + ( SAM(0,8,PIRQL) | SAM(CLOCK_VECTOR,0,PIV) ); + /* ^^ zero disables interrupt */ + + /* do not restore old vector */ + + } +} + +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(CLOCK_VECTOR); + } + else if (args->command == rtems_build_name('N', 'E', 'W', ' ')) + { + ReInstall_clock(args->buffer); + } + +done: + return RTEMS_SUCCESSFUL; +} + diff --git a/c/src/lib/libbsp/m68k/efi332/console/console.c b/c/src/lib/libbsp/m68k/efi332/console/console.c new file mode 100644 index 0000000000..b16ec72334 --- /dev/null +++ b/c/src/lib/libbsp/m68k/efi332/console/console.c @@ -0,0 +1,390 @@ +/* + * This file contains the efi332 console IO package. + * + * 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 +#include +#include + +/* BUFFER_LENGTH must be 2^n for n=1, 2, 3, .... */ +#define BUFFER_LENGTH 256 +#define RTS_STOP_SIZE BUFFER_LENGTH-64 +#define RTS_START_SIZE 16 + +char xmt_buf[BUFFER_LENGTH]; +char rcv_buf[BUFFER_LENGTH]; +/* in: last entry into the buffer; always on a valid character */ +/* out: points to the next character to be pull from the buffer */ +/* in+1=out => buffer empty */ +/* in+2=out => buffer full */ +struct UART_buf { + char *offset; + char *in; + char *out; +}; +static volatile struct UART_buf xmt = { xmt_buf, (char *)0, (char *)1}; +static volatile struct UART_buf rcv = { rcv_buf, (char *)0, (char *)1}; +static volatile char _debug_flag = 0; + +#define SET_RTS(a) {*PORTF0 = (*PORTF0 & 0x4) | ( (a)? 0 : 0x4); } +#define GET_CTS (!(*PORTF0 & 0x2)) + +/* _catchSCIint, _catchCTSint, and _catchSPURIOUSint are the + interrupt front-ends */ +extern void _catchSCIint(); +asm(" .text + .align 2 + .globl _catchSCIint +_catchSCIint: + moveml %d0-%d7/%a0-%a6,%sp@- /* save registers */ + jbsr uart_interrupt + moveml %sp@+,%d0-%d7/%a0-%a6 + rte + "); + +extern void _catchCTSint(); +asm(" .text + .align 2 + .globl _catchCTSint +_catchCTSint: + moveml %d0-%d7/%a0-%a6,%sp@- /* save registers */ + jbsr cts_interrupt + moveml %sp@+,%d0-%d7/%a0-%a6 + rte + "); + +extern void _catchSPURIOUSint(); +asm(" .text + .align 2 + .globl _catchSPURIOUSint +_catchSPURIOUSint: + moveml %d0-%d7/%a0-%a6,%sp@- /* save registers */ + jbsr spurious_interrupt + moveml %sp@+,%d0-%d7/%a0-%a6 + rte + "); + +int _spurious_int_counter=0; + +/* note: cts uses int1. If it "bounces", a spurious interrupt is generated */ +void spurious_interrupt(void) { + _spurious_int_counter++; /* there should never be alot of these */ +} + +/* _fake_trap_1 will continue the UART interrupt (%sr *still* + UART_ISR_LEVEL) as a trap #1 to enter the debugger */ + +/* *****fix me; this is for 68000 w/jsr ram exception table ******* */ +asm(" .text + .align 2 +_fake_trap_1: + unlk %a6 /* clear interrupt frame */ + lea %sp@(4),%sp /* remove jbsr instruction */ + moveml %sp@+,%d0-%d7/%a0-%a6 /* pop registers */ + jmp (33*6-12) /* jump exception 1 */ + "); + +/* dispatch UART interrupt */ +void xmit_interrupt(void); +void rcvr_interrupt(void); +void _fake_trap_1(void); + +void uart_interrupt(void) { + /* receiver status bits are cleared by a SCSR read followed + by a SCDR read. transmitter status bits are cleared by + a SCSR read followed by a SCDR write. */ + if ((*SCSR) & (TDRE | TC)) + xmit_interrupt(); + + if ((*SCSR) & (RDRF)) + rcvr_interrupt(); + + if (_debug_flag) { + _debug_flag = 0; /* reset the flag */ + _fake_trap_1(); /* fake a trap #1 */ + } +} + +/* transfer received character to the buffer */ +void rcvr_interrupt(void) { + register char *a, c; + register int length; + + while((*SCSR) & (RDRF)) { + if ((c=*SCDR) == 0x1a) /* use ctl-z to reboot */ + reboot(); +/* else if (c == 0x03) { */ /* use ctl-c to enter debugger */ +/* _debug_flag = 1; */ +/* continue; */ +/* } */ + + *(char *)((int)rcv.offset +(int) + (a=(char *)(((int)rcv.in+1) & ((int)BUFFER_LENGTH-1)))) = c; + if ((char *)(((int)rcv.in+2) & ((int)BUFFER_LENGTH-1)) != rcv.out) + rcv.in=a; + }; + + length = (BUFFER_LENGTH -1) & ( + ( ((int)rcv.out <= (int)rcv.in) ? 0 : BUFFER_LENGTH) - (int)rcv.out + + (int)rcv.in + 1); + if (length >= RTS_STOP_SIZE) + SET_RTS(0); +} + +/* tranfer buffered characters to the UART */ +void xmit_interrupt(void) { + register short int oldsr; + + _CPU_ISR_Disable( oldsr ); /* for when outbyte or flush calls */ + while ((*SCSR) & (TDRE)) { + if ((char *)(((int)xmt.in+1) & ((int)BUFFER_LENGTH-1)) != xmt.out) + /* xmit buffer not empty */ + if (GET_CTS) { + /* send next char */ + *SCDR=*(char *)((int)xmt.offset+(int)xmt.out); + xmt.out= (char *)(((int)xmt.out+1) & ((int)BUFFER_LENGTH-1)); + *SCCR1 = (*SCCR1 & ~(TIE | TCIE)) | (TIE); + } + else { + /* configue CTS interrupt and shutdown xmit interrupts */ + *SCCR1 &= ~(TIE | TCIE); + *PFPAR |= 0x2; + break; + } + else { + /* xmit buffer empty; shutdown interrupts */ + *SCCR1 &= ~(TIE | TCIE); + break; + } + } + _CPU_ISR_Enable( oldsr ); +} + +void cts_interrupt(void) { + register short int oldsr; + + _CPU_ISR_Disable( oldsr ); /* for when outbyte calls */ + + *PFPAR &= ~0x2; + *SCCR1 = (*SCCR1 & ~(TIE | TCIE)) | (TIE); + + _CPU_ISR_Enable( oldsr ); +} + + + +/* transfer character from the buffer */ +char inbyte(void) { + register char a; + register int length; + + while ((char *)(((int)rcv.in+1) & ((int)BUFFER_LENGTH-1))== rcv.out); + a=*(char *)((int)rcv.offset+(int)rcv.out); + rcv.out= (char *)(((int)rcv.out+1) & ((int)BUFFER_LENGTH-1)); + length = (BUFFER_LENGTH -1) & ( + ( ((int)rcv.out <= (int)rcv.in) ? 0 : BUFFER_LENGTH) - (int)rcv.out + + (int)rcv.in + 1); + if (length < RTS_START_SIZE) + SET_RTS(1); + return (a); +} + +/* once room is avaliable in the buffer, transfer + the character into the buffer and enable + the xmtr interrupt */ +void outbyte(char c) { + register char *a; + + while ((char *)(((int)xmt.in+2) & ((int)BUFFER_LENGTH-1)) == xmt.out); + *(char *)((int)xmt.offset+(int) + (a=(char *)(((int)xmt.in+1) & ((int)BUFFER_LENGTH-1))))=c; + xmt.in=a; + + if (!(*SCCR1 & (TIE | TCIE)) && (!(*PFPAR & 0x2)) ) + /* if neither interrupts are running, */ + xmit_interrupt(); /* we need to restart the xmiter */ +} + +void _UART_flush(void) { + /* loop till xmt buffer empty. Works with interrupts disabled */ + while ((char *)(((int)xmt.in+1) & ((int)BUFFER_LENGTH-1)) != xmt.out) + xmit_interrupt(); + /* loop till UART buffer empty */ + while ( (*SCSR & TC) == 0 ); +} + +/* 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; + + *QSMCR = ( SAM(QSM_IARB,0,IARB) ); + *QILR = ( SAM(ISRL_QSPI,4,ILQSPI) | SAM(ISRL_SCI,0,ILSCI) ); + *QIVR = ( SAM(EFI_QIVR,0,INTV) ); + + *SCCR0 = ( (int)( SYS_CLOCK/SCI_BAUD/32.0+0.5 ) & 0x1fff ); + *SCCR1 = ( RIE | TE | RE ); + + set_vector(_catchSPURIOUSint, EFI_SPINT, 0); + set_vector(_catchSCIint, EFI_QIVR, 0); + set_vector(_catchCTSint, EFI_INT1, 0); + 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 +) +{ + if ((char *)(((int)rcv.in+1) & ((int)BUFFER_LENGTH-1))== rcv.out) + return(FALSE); + else + return(TRUE); +} + +/* + * 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 ] ); + } + + rw_args->bytes_moved = maximum; + return 0; +} + +/* + * 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/libbsp/m68k/efi332/include/bsp.h b/c/src/lib/libbsp/m68k/efi332/include/bsp.h new file mode 100644 index 0000000000..dd876eeeec --- /dev/null +++ b/c/src/lib/libbsp/m68k/efi332/include/bsp.h @@ -0,0 +1,147 @@ +/* bsp.h + * + * This include file contains all efi332 board IO definitions. + * + * 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$ + */ + +#ifndef __EFI332_BSP_h +#define __EFI332_BSP_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include +#include +#include + +/* + * Define the time limits for RTEMS Test Suite test durations. + * Long test and short test duration limits are provided. These + * values are in seconds and need to be converted to ticks for the + * application. + * + */ + +#define MAX_LONG_TEST_DURATION 300 /* 5 minutes = 300 seconds */ +#define MAX_SHORT_TEST_DURATION 3 /* 3 seconds */ + +/* + * Define the interrupt mechanism for Time Test 27 + */ + +/* XXX - JRS - I want to compile the tmtests */ + +#define MUST_WAIT_FOR_INTERRUPT 1 + +#define Install_tm27_vector( handler ) + +#define Cause_tm27_intr() + +#define Clear_tm27_intr() + +#define Lower_tm27_intr() + +/* + * Simple spin delay in microsecond units for device drivers. + * This is very dependent on the clock speed of the target. + */ + +#define delay( microseconds ) \ + { register rtems_unsigned32 _delay=(microseconds); \ + register rtems_unsigned32 _tmp=123; \ + asm volatile( "0: \ + nbcd %0 ; \ + nbcd %0 ; \ + dbf %1,0b" \ + : "=d" (_tmp), "=d" (_delay) \ + : "0" (_tmp), "1" (_delay) ); \ + } + +/* macros */ + +#define RAM_START 0x80000 +#define RAM_END 0xc0000 + +#define RAW_PUTS(str) \ + { register char *ptr = str; \ + while (*ptr) outbyte(*ptr++); \ + } + +#define RAW_PUTI(n) { \ + register int i, j; \ + \ + RAW_PUTS("0x"); \ + for (i=28;i>=0;i -= 4) { \ + j = (n>>i) & 0xf; \ + outbyte( (j>9 ? j-10+'a' : j+'0') ); \ + } \ + } + +/* miscellaneous stuff assumed to exist */ + +extern rtems_configuration_table BSP_Configuration; + +extern m68k_isr_entry M68Kvec[]; /* vector table address */ + +extern int stack_size; + +extern int stack_start; + +/* + * Device Driver Table Entries + */ + +/* + * NOTE: Use the standard Console driver entry + */ + +/* + * NOTE: Use the standard Clock driver entry + */ + +/* + * How many libio files we want + */ + +#define BSP_LIBIO_MAX_FDS 20 + +/* functions */ + +void bsp_cleanup( void ); + +m68k_isr_entry set_vector( + rtems_isr_entry handler, + rtems_vector_number vector, + int type +); + +void console_init(void); + +void Spurious_Initialize(void); + +void _UART_flush(void); + +void Clock_exit(void); + +void outbyte(char); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/c/src/lib/libbsp/m68k/efi332/include/coverhd.h b/c/src/lib/libbsp/m68k/efi332/include/coverhd.h new file mode 100644 index 0000000000..671f20d197 --- /dev/null +++ b/c/src/lib/libbsp/m68k/efi332/include/coverhd.h @@ -0,0 +1,106 @@ +/* coverhd.h + * + * This include file has defines to represent the overhead associated + * with calling a particular directive from C. These are used in the + * Timing Test Suite to ignore the overhead required to pass arguments + * to directives. On some CPUs and/or target boards, this overhead + * is significant and makes it difficult to distinguish internal + * RTEMS execution time from that used to call the directive. + * This file should be updated after running the C overhead timing + * test. Once this update has been performed, the RTEMS Time Test + * Suite should be rebuilt to account for these overhead times in the + * timing results. + * + * NOTE: If these are all zero, then the times reported include all + * all calling overhead including passing of arguments. + * + * 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$ + */ + +#ifndef __COVERHD_h +#define __COVERHD_h + +#define CALLING_OVERHEAD_INITIALIZE_EXECUTIVE 0 +#define CALLING_OVERHEAD_SHUTDOWN_EXECUTIVE 0 +#define CALLING_OVERHEAD_TASK_CREATE 0 +#define CALLING_OVERHEAD_TASK_IDENT 0 +#define CALLING_OVERHEAD_TASK_START 0 +#define CALLING_OVERHEAD_TASK_RESTART 0 +#define CALLING_OVERHEAD_TASK_DELETE 0 +#define CALLING_OVERHEAD_TASK_SUSPEND 0 +#define CALLING_OVERHEAD_TASK_RESUME 0 +#define CALLING_OVERHEAD_TASK_SET_PRIORITY 0 +#define CALLING_OVERHEAD_TASK_MODE 0 +#define CALLING_OVERHEAD_TASK_GET_NOTE 0 +#define CALLING_OVERHEAD_TASK_SET_NOTE 0 +#define CALLING_OVERHEAD_TASK_WAKE_WHEN 0 +#define CALLING_OVERHEAD_TASK_WAKE_AFTER 0 +#define CALLING_OVERHEAD_INTERRUPT_CATCH 0 +#define CALLING_OVERHEAD_CLOCK_GET 0 +#define CALLING_OVERHEAD_CLOCK_SET 0 +#define CALLING_OVERHEAD_CLOCK_TICK 0 + +#define CALLING_OVERHEAD_TIMER_CREATE 0 +#define CALLING_OVERHEAD_TIMER_IDENT 0 +#define CALLING_OVERHEAD_TIMER_DELETE 0 +#define CALLING_OVERHEAD_TIMER_FIRE_AFTER 0 +#define CALLING_OVERHEAD_TIMER_FIRE_WHEN 0 +#define CALLING_OVERHEAD_TIMER_RESET 0 +#define CALLING_OVERHEAD_TIMER_CANCEL 0 +#define CALLING_OVERHEAD_SEMAPHORE_CREATE 0 +#define CALLING_OVERHEAD_SEMAPHORE_IDENT 0 +#define CALLING_OVERHEAD_SEMAPHORE_DELETE 0 +#define CALLING_OVERHEAD_SEMAPHORE_OBTAIN 0 +#define CALLING_OVERHEAD_SEMAPHORE_RELEASE 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_CREATE 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_IDENT 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_DELETE 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_SEND 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_URGENT 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_BROADCAST 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_RECEIVE 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_FLUSH 0 + +#define CALLING_OVERHEAD_EVENT_SEND 0 +#define CALLING_OVERHEAD_EVENT_RECEIVE 0 +#define CALLING_OVERHEAD_SIGNAL_CATCH 0 +#define CALLING_OVERHEAD_SIGNAL_SEND 0 +#define CALLING_OVERHEAD_PARTITION_CREATE 0 +#define CALLING_OVERHEAD_PARTITION_IDENT 0 +#define CALLING_OVERHEAD_PARTITION_DELETE 0 +#define CALLING_OVERHEAD_PARTITION_GET_BUFFER 0 +#define CALLING_OVERHEAD_PARTITION_RETURN_BUFFER 0 +#define CALLING_OVERHEAD_REGION_CREATE 0 +#define CALLING_OVERHEAD_REGION_IDENT 0 +#define CALLING_OVERHEAD_REGION_DELETE 0 +#define CALLING_OVERHEAD_REGION_GET_SEGMENT 0 +#define CALLING_OVERHEAD_REGION_RETURN_SEGMENT 0 +#define CALLING_OVERHEAD_PORT_CREATE 0 +#define CALLING_OVERHEAD_PORT_IDENT 0 +#define CALLING_OVERHEAD_PORT_DELETE 0 +#define CALLING_OVERHEAD_PORT_EXTERNAL_TO_INTERNAL 0 +#define CALLING_OVERHEAD_PORT_INTERNAL_TO_EXTERNAL 0 + +#define CALLING_OVERHEAD_IO_INITIALIZE 0 +#define CALLING_OVERHEAD_IO_OPEN 0 +#define CALLING_OVERHEAD_IO_CLOSE 0 +#define CALLING_OVERHEAD_IO_READ 0 +#define CALLING_OVERHEAD_IO_WRITE 0 +#define CALLING_OVERHEAD_IO_CONTROL 0 +#define CALLING_OVERHEAD_FATAL_ERROR_OCCURRED 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_CREATE 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_IDENT 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_DELETE 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_CANCEL 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_PERIOD 0 +#define CALLING_OVERHEAD_MULTIPROCESSING_ANNOUNCE 0 + +#endif diff --git a/c/src/lib/libbsp/m68k/efi332/include/efi332.h b/c/src/lib/libbsp/m68k/efi332/include/efi332.h new file mode 100644 index 0000000000..80d23f291a --- /dev/null +++ b/c/src/lib/libbsp/m68k/efi332/include/efi332.h @@ -0,0 +1,46 @@ +/* efi332.h + * + * $Id$ + */ + +#ifndef _EFI332_H_ +#define _EFI332_H_ + + +/* SIM_MM (SIM Module Mapping) determines the location of the control + register block. When MM=0, register addresses range fom 0x7ff000 to + 0x7FFFFF. When MM=1, register addresses range from 0xfff000 to + 0xffffff. */ +#define SIM_MM 1 + + +/* Interrupt related definitions */ +#define SIM_IARB 15 +#define QSM_IARB 10 + +#define EFI_PIV 64 +#define ISRL_PIT 4 /* zero disables PIT */ + +#define EFI_QIVR 66 /* 66=>SCI and 67=>QSPI interrupt */ +#define ISRL_QSPI 0 + +#define EFI_SPINT 24 /* spurious interrupt */ +#define EFI_INT1 25 /* CTS interrupt */ +#define ISRL_SCI 6 + + + +/* System Clock definitions */ +#define XTAL 32768.0 /* crystal frequency in Hz */ +#define EFI_W 0 /* system clock parameters */ +#define EFI_X 1 +#define EFI_Y 0x38 +#define SYS_CLOCK (XTAL*4.0*(EFI_Y+1)*(1 << (2*EFI_W+EFI_X))) +#define SCI_BAUD 19200 /* RS232 Baud Rate */ + + +/* macros/functions */ +static void reboot(void) __attribute__ ((noreturn)); +__inline__ static void reboot() {asm("trap #15");} + +#endif /* _EFI332_H_ */ diff --git a/c/src/lib/libbsp/m68k/efi332/spurious/spinit.c b/c/src/lib/libbsp/m68k/efi332/spurious/spinit.c new file mode 100644 index 0000000000..3370cb0e30 --- /dev/null +++ b/c/src/lib/libbsp/m68k/efi332/spurious/spinit.c @@ -0,0 +1,85 @@ +/* Spurious_driver + * + * This routine installs spurious interrupt handlers for the efi332. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993. + * On-Line Applications Research Corporation (OAR). + * + * 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 +#include + +const char * const _Spurious_Error_[] = {"Reset","Bus Error","Address Error", + "Illegal Instruction","Zero Division","CHK, CHK2 Instruction", + "TRAPcc, TRAPV Instruction","Privilege Violation","Trace", + "Line 1010 Emulation","Line 1111 Emulation","Hardware Breakpoint", + "Coprocessor Protocal Violation", + "Format Error ans Uninitialized Interrupt","Unassigned", + "Spurious Interrupt","AVec1","AVec2","AVec3","AVec4","AVec5","AVec6", + "AVec7","Trap Instruction","Debug","Reboot","Reserved Coprocessor", + "Reserved Unassigned","User Defined"}; + +rtems_isr Spurious_Isr( + rtems_vector_number vector +) +{ + int sp = 0; + const char * const VectDescrip[] = { + _Spurious_Error_[0], _Spurious_Error_[0], _Spurious_Error_[1], + _Spurious_Error_[2], _Spurious_Error_[3], _Spurious_Error_[4], + _Spurious_Error_[5], _Spurious_Error_[6], _Spurious_Error_[7], + _Spurious_Error_[8], _Spurious_Error_[9], _Spurious_Error_[10], + _Spurious_Error_[11], _Spurious_Error_[12], _Spurious_Error_[13], + _Spurious_Error_[13], _Spurious_Error_[14], _Spurious_Error_[14], + _Spurious_Error_[14], _Spurious_Error_[14], _Spurious_Error_[14], + _Spurious_Error_[14], _Spurious_Error_[14], _Spurious_Error_[14], + _Spurious_Error_[15], _Spurious_Error_[16], _Spurious_Error_[17], + _Spurious_Error_[18], _Spurious_Error_[19], _Spurious_Error_[20], + _Spurious_Error_[21], _Spurious_Error_[22], _Spurious_Error_[23], + _Spurious_Error_[24], _Spurious_Error_[23], _Spurious_Error_[23], + _Spurious_Error_[23], _Spurious_Error_[23], _Spurious_Error_[23], + _Spurious_Error_[23], _Spurious_Error_[23], _Spurious_Error_[23], + _Spurious_Error_[23], _Spurious_Error_[23], _Spurious_Error_[23], + _Spurious_Error_[23], _Spurious_Error_[23], _Spurious_Error_[25], + _Spurious_Error_[26], _Spurious_Error_[26], _Spurious_Error_[26], + _Spurious_Error_[26], _Spurious_Error_[26], _Spurious_Error_[26], + _Spurious_Error_[26], _Spurious_Error_[26], _Spurious_Error_[26], + _Spurious_Error_[26], _Spurious_Error_[26], _Spurious_Error_[27], + _Spurious_Error_[27], _Spurious_Error_[27], _Spurious_Error_[27], + _Spurious_Error_[27], _Spurious_Error_[28]}; + + asm volatile ( "movea.l %%sp,%0 " : "=a" (sp) : "0" (sp) ); + + _CPU_ISR_Set_level( 7 ); + _UART_flush(); + + RAW_PUTS("\n\rRTEMS: Spurious interrupt: "); + RAW_PUTS((char *)VectDescrip[( (vector>64) ? 64 : vector )]); + RAW_PUTS("\n\rRTEMS: Vector: "); + RAW_PUTI(vector); + RAW_PUTS(" sp: "); + RAW_PUTI(sp); + RAW_PUTS("\n\r"); + + bsp_cleanup(); + + for(;;); +} + +void Spurious_Initialize(void) +{ + rtems_vector_number vector; + + for ( vector = 0x0 ; vector <= 0xFF ; vector++ ) + (void) set_vector( Spurious_Isr, vector, 1 ); +} diff --git a/c/src/lib/libbsp/m68k/efi332/startup/bspclean.c b/c/src/lib/libbsp/m68k/efi332/startup/bspclean.c new file mode 100644 index 0000000000..34a57b6b68 --- /dev/null +++ b/c/src/lib/libbsp/m68k/efi332/startup/bspclean.c @@ -0,0 +1,28 @@ +/* bsp_cleanup() + * + * This routine cleans up in the sense that it places the board + * in a safe state and flushes the I/O buffers before exiting. + * + * INPUT: NONE + * + * OUTPUT: NONE + * + * 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 + +void bsp_cleanup(void) +{ + /* interrupt driven stdio must be flushed */ + _CPU_ISR_Set_level( 7 ); + _UART_flush(); +} diff --git a/c/src/lib/libbsp/m68k/efi332/startup/bspstart.c b/c/src/lib/libbsp/m68k/efi332/startup/bspstart.c new file mode 100644 index 0000000000..6a7830bcfe --- /dev/null +++ b/c/src/lib/libbsp/m68k/efi332/startup/bspstart.c @@ -0,0 +1,220 @@ +#define STACK_CHECKER_ON +/* bsp_start() + * + * This routine starts the application. It includes application, + * board, and monitor specific initialization and configuration. + * The generic CPU dependent initialization has been performed + * before this routine is invoked. + * + * INPUT: NONE + * + * OUTPUT: NONE + * + * 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 +#include +#include + +#include +#include + +#ifdef STACK_CHECKER_ON +#include +#endif + +/* + * The original table from the application and our copy of it with + * some changes. + */ + +extern rtems_configuration_table Configuration; +rtems_configuration_table BSP_Configuration; + +rtems_cpu_table Cpu_table; + +char *rtems_progname; + +/* Initialize whatever libc we are using + * called from postdriver hook + */ + +void bsp_libc_init() +{ + extern int end; + rtems_unsigned32 heap_start; + + heap_start = (rtems_unsigned32) &end; + if (heap_start & (CPU_ALIGNMENT-1)) + heap_start = (heap_start + CPU_ALIGNMENT) & ~(CPU_ALIGNMENT-1); + + RTEMS_Malloc_Initialize((void *) heap_start, 64 * 1024, 0); + + /* + * Init the RTEMS libio facility to provide UNIX-like system + * calls for use by newlib (ie: provide __open, __close, etc) + * Uses malloc() to get area for the iops, so must be after malloc init + */ + + rtems_libio_init(); + + /* + * Set up for the libc handling. + */ + + if (BSP_Configuration.ticks_per_timeslice > 0) + libc_init(1); /* reentrant if possible */ + else + libc_init(0); /* non-reentrant */ +} + +/* + * Function: bsp_pretasking_hook + * Created: 95/03/10 + * + * Description: + * BSP pretasking hook. Called just before drivers are initialized. + * Used to setup libc and install any BSP extensions. + * + * NOTES: + * Must not use libc (to do io) from here, since drivers are + * not yet initialized. + * + */ + +void +bsp_pretasking_hook(void) +{ + bsp_libc_init(); + +#ifdef STACK_CHECKER_ON + /* + * Initialize the stack bounds checker + * We can either turn it on here or from the app. + */ + + Stack_check_Initialize(); +#endif + +#ifdef RTEMS_DEBUG + rtems_debug_enable( RTEMS_DEBUG_ALL_MASK ); +#endif +} + + +/* + * After drivers are setup, register some "filenames" + * and open stdin, stdout, stderr files + * + * Newlib will automatically associate the files with these + * (it hardcodes the numbers) + */ + +void +bsp_postdriver_hook(void) +{ + int stdin_fd, stdout_fd, stderr_fd; + + if ((stdin_fd = __open("/dev/console", O_RDONLY, 0)) == -1) + rtems_fatal_error_occurred('STD0'); + + if ((stdout_fd = __open("/dev/console", O_WRONLY, 0)) == -1) + rtems_fatal_error_occurred('STD1'); + + if ((stderr_fd = __open("/dev/console", O_WRONLY, 0)) == -1) + rtems_fatal_error_occurred('STD2'); + + if ((stdin_fd != 0) || (stdout_fd != 1) || (stderr_fd != 2)) + rtems_fatal_error_occurred('STIO'); +} + +int main( + int argc, + char **argv, + char **environp +) +{ + void *vbr; + + /* + * we only use a hook to get the C library initialized. + */ + + Cpu_table.pretasking_hook = bsp_pretasking_hook; + + Cpu_table.predriver_hook = NULL; + + Cpu_table.postdriver_hook = bsp_postdriver_hook; + + Cpu_table.idle_task = NULL; /* do not override system IDLE task */ + + Cpu_table.do_zero_of_workspace = TRUE; + + m68k_get_vbr( vbr ); + Cpu_table.interrupt_vector_table = vbr; + + Cpu_table.interrupt_stack_size = 4096; + + Cpu_table.extra_system_initialization_stack = 0; + + /* + * Copy the table + */ + + BSP_Configuration = Configuration; + + BSP_Configuration.work_space_start = (void *) + (RAM_END - BSP_Configuration.work_space_size); + + if ((unsigned int)BSP_Configuration.work_space_start < + (unsigned int)((stack_start + stack_size) & 0xffffffc0) ) { + /* rtems_fatal_error_occurred can not be used before initalization */ + RAW_PUTS("\n\rRTEMS: Out of memory.\n\r"); + RAW_PUTS("RTEMS: Check RAM_END and the size of the work space.\n\r"); + goto exit; + } + + /* + * Add 1 region for Malloc in libc_low + */ + + BSP_Configuration.maximum_regions++; + + /* + * Add 1 extension for newlib libc + */ + +#ifdef RTEMS_NEWLIB + BSP_Configuration.maximum_extensions++; +#endif + + /* + * Add another extension if using the stack checker + */ + +#ifdef STACK_CHECKER_ON + BSP_Configuration.maximum_extensions++; +#endif + + rtems_initialize_executive( &BSP_Configuration, &Cpu_table ); + /* does not return */ + + /* Clock_exit is done as an atexit() function */ + +exit: + /* configure peripherals for safe exit */ + bsp_cleanup(); + + /* return like a "normal" subroutine to the monitor */ + return 0; +} + diff --git a/c/src/lib/libbsp/m68k/efi332/startup/linkcmds b/c/src/lib/libbsp/m68k/efi332/startup/linkcmds new file mode 100644 index 0000000000..37d1eb5667 --- /dev/null +++ b/c/src/lib/libbsp/m68k/efi332/startup/linkcmds @@ -0,0 +1,100 @@ +/* linkcmds + * + * $Id$ + */ + +OUTPUT_ARCH(m68k) +__DYNAMIC = 0; + +/* + * The memory map looks like this: + * +--------------------+ <- low memory + * | .text | + * | etext | + * | ctor list | the ctor and dtor lists are for + * | dtor list | C++ support + * | _endtext | + * +--------------------+ + * | .data | initialized data goes here + * | _sdata | + * | _edata | + * +--------------------+ + * | .bss | + * | __bss_start | start of bss, cleared by crt0 + * | _end | start of heap, used by sbrk() + * +--------------------+ + * | heap space | + * | _ENDHEAP | + * | stack space | + * | __stack | top of stack + * +--------------------+ <- high memory + */ + +MEMORY +{ + ram : ORIGIN = 0x80000, LENGTH = 256K +} + +_copy_data_from_rom = 0; + +/* + * stick everything in ram (of course) + */ +SECTIONS +{ + .text : + { + CREATE_OBJECT_SYMBOLS + text_start = .; + _text_start = .; + *(.text) + etext = ALIGN(0x10); + _etext = .; + __CTOR_LIST__ = .; + LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2) + *(.ctors) + LONG(0) + __CTOR_END__ = .; + __DTOR_LIST__ = .; + LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2) + *(.dtors) + LONG(0) + __DTOR_END__ = .; + *(.lit) + *(.shdata) + _endtext = .; + } > ram + .data : + { + data_start = .; + _data_start = .; + _sdata = . ; + *(.data) + CONSTRUCTORS + edata = ALIGN(0x10); + _edata = .; + } > ram + .shbss : + { + *(.shbss) + } > ram + .bss : + { + __bss_start = ALIGN(0x8); + bss_start = .; + _bss_start = .; + *(.bss) + *(COMMON) + end = .; + _end = ALIGN(0x8); + __end = ALIGN(0x8); + } > ram + .stab . (NOLOAD) : + { + [ .stab ] + } + .stabstr . (NOLOAD) : + { + [ .stabstr ] + } +} diff --git a/c/src/lib/libbsp/m68k/efi332/timer/timer.c b/c/src/lib/libbsp/m68k/efi332/timer/timer.c new file mode 100644 index 0000000000..7a9b1b6267 --- /dev/null +++ b/c/src/lib/libbsp/m68k/efi332/timer/timer.c @@ -0,0 +1,84 @@ +/* Timer_init() + * + * This routine initializes a timer in efi68k's DP8570A TCP + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * NOTE: It is important that the timer start/stop overhead be + * determined when porting or modifying this code. + * + * 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 + +rtems_boolean Timer_driver_Find_average_overhead; + +extern rtems_isr Clock_isr(); + +void Timer_initialize( void ) +{ +} + +/* + * The following controls the behavior of Read_timer(). + * + * FIND_AVG_OVERHEAD * instructs the routine to return the "raw" count. + * + * AVG_OVEREHAD is the overhead for starting and stopping the timer. It + * is usually deducted from the number returned. + * + * LEAST_VALID is the lowest number this routine should trust. Numbers + * below this are "noise" and zero is returned. + */ + +#define AVG_OVERHEAD 0 /* It typically takes X.X microseconds */ + /* (Y countdowns) to start/stop the timer. */ + /* This value is in microseconds. */ +#define LEAST_VALID 1 /* Don't trust a clicks value lower than this */ + +/* + * Return timer value in 1/2-microsecond units + */ +int Read_timer( void ) +{ + rtems_unsigned32 total; + total = 0; + + if ( Timer_driver_Find_average_overhead == 1 ) + return total; /* in XXX microsecond units */ + + if ( total < LEAST_VALID ) + return 0; /* below timer resolution */ + + return (total - AVG_OVERHEAD); +} + + +/* + * Empty function call used in loops to measure basic cost of looping + * in Timing Test Suite. + */ + +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/libbsp/m68k/efi68k/README b/c/src/lib/libbsp/m68k/efi68k/README new file mode 100644 index 0000000000..7a431fd48b --- /dev/null +++ b/c/src/lib/libbsp/m68k/efi68k/README @@ -0,0 +1,48 @@ +# +# $Id$ +# + +Description: efi68k +============ +CPU: MC68HC000 @16MHz +RAM: 256k +ROM: 256k + + Based upon a 16MHz 68HC000, efi332 is a minimally configured 4x6 +inch single board computer. It includes the following major +components: (a) 256k SRAM (km681000l), (b) 256 EPROM (27C010), +(c) DP8570A (clock/timer/calendar), (d) MAX791 (cpu supervisory chip +with battery backup switch-over and watch dog timer), and +(e) NS16550DN (UART). The following interrupt functions have also been +incorporated: UART, TIMER, Watch Dog, and Low Line voltage (trips at +4.85V; enough time to save the cpu reg before reset is asserted on +power down). + The schematic for efi68k is freely available via e-mail. Send +"index diy_efi" to majordomo@coulomb.eng.ohio-state.edu. Retrieve the +files related to 68hc000-1.00 with the "get diy_efi " +command. efi68k does not have an available printed circuit board, but +can be wire-wrapped in about four days. Cost is about $100US. + +For more information, I can be contacted at the address below. + + +TODO: +===== +- add separate interrupt stack (low priority). + +- add the "tm27 vector" ... can we use a trap instruction? + +- generate include/coverhd.c to preform the tmtest. + +- the interrupt drive I/O should be integrated into the RTEMS. + +- finish the ROM memory model. + + John S Gwynne + Gwynne.1@osu.edu +_______________________________________________________________________________ + T h e O h i o - S t a t e U n i v e r s i t y + ElectroScience Laboratory, 1320 Kinnear Road, Columbus, Ohio 43212, USA + Telephone: (614) 292-7981 * Fax: (614) 292-7297 +------------------------------------------------------------------------------- + diff --git a/c/src/lib/libbsp/m68k/efi68k/clock/ckinit.c b/c/src/lib/libbsp/m68k/efi68k/clock/ckinit.c new file mode 100644 index 0000000000..c90eba1e22 --- /dev/null +++ b/c/src/lib/libbsp/m68k/efi68k/clock/ckinit.c @@ -0,0 +1,165 @@ +/* Clock_init() + * + * This routine initializes the DP8570A periodic interrupt on the + * efi68k board. The tick frequency is 1 millisecond. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * 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 +#include +#include + +#define CLOCK_VECTOR (TCP_ISR_LEVEL+24) + +rtems_unsigned32 Clock_isrs; /* ISRs until next tick */ +volatile rtems_unsigned32 Clock_driver_ticks; + /* ticks since initialization */ +rtems_isr_entry Old_ticker; + +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; + + +void per_interrupt(void) +{ + Clock_driver_ticks += 1; + + *MSR = PER; + + if ( Clock_isrs == 1 ) { + rtems_clock_tick(); + Clock_isrs = BSP_Configuration.microseconds_per_tick / 1000; + } + else + Clock_isrs -= 1; +} + +rtems_isr Clock_isr( + rtems_vector_number vector +) +{ + unsigned char entry_msr, msr; + + entry_msr = *MSR; + *MSR = 0; + while ( (msr=*MSR) & INT ) + /* test enabled interrupt bits */ + if (msr & PER) + per_interrupt(); + else if (msr & T0) { + *MSR = T0; /* reset interrupt */ + Timer_interrupts++; /* inc wrap around counter */ + } + else + /* there has been an error if we reach this point */ + /* default action: reset all the interrupts */ + *MSR = ( PER | AL | T0 | T1 ); + *MSR = entry_msr & (RS | PS); +} + +void Install_clock( + rtems_isr_entry clock_isr +) +{ + Clock_driver_ticks = 0; + Clock_isrs = BSP_Configuration.microseconds_per_tick / 1000; + + if ( BSP_Configuration.ticks_per_timeslice ) { + Old_ticker = (rtems_isr_entry) set_vector( clock_isr, CLOCK_VECTOR, 1 ); + + *MSR = RS; /* enable 1mS interrupts */ + *ICR0 |= OME; + + atexit( Clock_exit ); + } +} + +void ReInstall_clock( + rtems_isr_entry clock_isr +) +{ + rtems_unsigned32 isrlevel = 0 ; + + rtems_interrupt_disable( isrlevel ); + (void) set_vector( clock_isr, CLOCK_VECTOR, 1 ); + rtems_interrupt_enable( isrlevel ); +} + +void Clock_exit( void ) +{ + + if ( BSP_Configuration.ticks_per_timeslice ) { + + /* shutdown periodic interrupt */ + *MSR = RS; + *ICR0 &= 0xc0; + /* do not restore old vector */ + + } +} + +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(CLOCK_VECTOR); + } + else if (args->command == rtems_build_name('N', 'E', 'W', ' ')) + { + ReInstall_clock(args->buffer); + } + +done: + return RTEMS_SUCCESSFUL; +} diff --git a/c/src/lib/libbsp/m68k/efi68k/console/console.c b/c/src/lib/libbsp/m68k/efi68k/console/console.c new file mode 100644 index 0000000000..73e3cff1fe --- /dev/null +++ b/c/src/lib/libbsp/m68k/efi68k/console/console.c @@ -0,0 +1,363 @@ +/* + * This file contains the efi68k console IO package. + * + * 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 +#include +#include + + +#define BAUD 38400 +#define CLK_FREQ 8000000.0 + +/* BUFFER_LENGTH must be 2^n for n=1, 2, 3, .... */ +#define BUFFER_LENGTH 256 +#define RTS_STOP_SIZE BUFFER_LENGTH-64 +#define RTS_START_SIZE 16 + +char xmt_buf[BUFFER_LENGTH]; +char rcv_buf[BUFFER_LENGTH]; +/* in: last entry into the buffer; always on a valid character */ +/* out: points to the next character to be pull from the buffer */ +/* in+1=out => buffer empty */ +/* in+2=out => buffer full */ +struct UART_buf { + char *offset; + char *in; + char *out; +}; +static volatile struct UART_buf xmt = { xmt_buf, (char *)0, (char *)1}; +static volatile struct UART_buf rcv = { rcv_buf, (char *)0, (char *)1}; +static volatile char _debug_flag = 0; +static volatile char _tx_stop = 0; + +/* _catchUARTint is the interrupt front-end */ +extern void _catchUARTint(); +asm(" .text + .align 2 + .globl _catchUARTint +_catchUARTint: + lea %sp@(4),%sp /* pop return address */ + moveml %d0-%d7/%a0-%a6,%sp@- /* save registers */ + jbsr uart_interrupt + moveml %sp@+,%d0-%d7/%a0-%a6 + rte + "); + +/* _fake_trap_1 will continue the UART interrupt (%sr *still* + UART_ISR_LEVEL) as a trap #1 to enter the debugger */ +asm(" .text + .align 2 +_fake_trap_1: + unlk %a6 /* clear interrupt frame */ + lea %sp@(4),%sp /* remove jbsr instruction */ + moveml %sp@+,%d0-%d7/%a0-%a6 /* pop registers */ + jmp (33*6-12+_VBR) /* jump exception 1 */ + "); + +/* dispatch UART interrupt */ +void xmit_interrupt(void); +void rcvr_interrupt(void); +void modem_status(void); +void _fake_trap_1(void); +void uart_interrupt(void) { + register char a; + + a=*IIR & (NIP | IID_MASK); /* read interrupt id register */ + switch (a) { + case 0x04: case 0x0c: + rcvr_interrupt(); + break; + case 0x02: + xmit_interrupt(); + break; + case 0x00: + modem_status(); + break; + default: + break; + } + if (_debug_flag) { + _debug_flag = 0; /* reset the flag */ + _fake_trap_1(); /* fake a trap #1 */ + } +} + +/* transfer received character to the buffer */ +void rcvr_interrupt(void) { + register char *a, c; + register int length; + + while ( (*LSR & DR) != 0) { + if ((c=*RBR) == 0x1a) /* use ctl-z to reboot */ + reboot(); + else if (c == 0x03) { /* use ctl-c to enter debugger */ + _debug_flag = 1; + continue; + } + *(char *)((int)rcv.offset +(int) + (a=(char *)(((int)rcv.in+1) & ((int)BUFFER_LENGTH-1)))) = c; + if ((char *)(((int)rcv.in+2) & ((int)BUFFER_LENGTH-1)) != rcv.out) + rcv.in=a; + } + length = (BUFFER_LENGTH -1) & ( + ( ((int)rcv.out <= (int)rcv.in) ? 0 : BUFFER_LENGTH) - (int)rcv.out + + (int)rcv.in + 1); + if (length >= RTS_STOP_SIZE) + *MCR &= (char) (~RTS); +} + +/* tranfer buffered characters to the UART */ +void xmit_interrupt(void) { + register short int i, oldsr; + + _CPU_ISR_Disable( oldsr ); /* for when outbyte calls */ + if ( (*LSR & THRE) != 0 && _tx_stop == 0 ) + for (i=0;i<16;i++) { + if ((char *)(((int)xmt.in+1) & ((int)BUFFER_LENGTH-1))== xmt.out) + break; + *THR=*(char *)((int)xmt.offset+(int)xmt.out); + xmt.out= (char *)(((int)xmt.out+1) & ((int)BUFFER_LENGTH-1)); + } + _CPU_ISR_Enable( oldsr ); +} + +void modem_status(void) { + register char a; + + if ( ((a=*MDSR) & DCTS) != 0 ) + if ( (a & CTS) == 0) + _tx_stop = 1; + else { + _tx_stop = 0; + xmit_interrupt(); + } +} + +/* transfer character from the buffer */ +char inbyte(void) { + register char a; + register int length; + + while ((char *)(((int)rcv.in+1) & ((int)BUFFER_LENGTH-1))== rcv.out); + a=*(char *)((int)rcv.offset+(int)rcv.out); + rcv.out= (char *)(((int)rcv.out+1) & ((int)BUFFER_LENGTH-1)); + length = (BUFFER_LENGTH -1) & ( + ( ((int)rcv.out <= (int)rcv.in) ? 0 : BUFFER_LENGTH) - (int)rcv.out + + (int)rcv.in + 1); + if (length < RTS_START_SIZE) + *MCR |= (char) RTS; + return (a); +} + +/* once room is avaliable in the buffer, transfer + the character into the buffer and enable + the xmtr interrupt */ +void outbyte(char c) { + register char *a; + + while ((char *)(((int)xmt.in+2) & ((int)BUFFER_LENGTH-1)) == xmt.out); + *(char *)((int)xmt.offset+(int) + (a=(char *)(((int)xmt.in+1) & ((int)BUFFER_LENGTH-1))))=c; + xmt.in=a; + + if ( (*LSR & THRE) != 0 ) /* if THRE, uart has already interrupted */ + xmit_interrupt(); /* and was ignored. Need to restart. */ +} + +void _UART_flush(void) { + /* loop till xmt buffer empty. Works with interrupts disabled */ + while ((char *)(((int)xmt.in+1) & ((int)BUFFER_LENGTH-1)) != xmt.out) + xmit_interrupt(); + /* loop till UART buffer empty */ + while ( (*LSR & TEMT) == 0 ); +} + +/* 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; + + /* set clock divisor */ + *LCR = (char)(DLAB); + *DLL = (char)((int)(CLK_FREQ/BAUD/16.0+0.5) & 0xFF); + *DLM = (char)(((int)(CLK_FREQ/BAUD/16.0+0.5) & 0xFF00) >> 8); + + /* Line control setup */ + *LCR = (char)(WL_8 | NSB); + + /* Interrupt setup */ + *IER = (char) 0x0b; /* enable transmit, receive, modem stat int */ + + /* FIFO setup */ + *FCR = (char)(FIFO_E | 0xc0); + + /* Modem control setup */ + *MCR = (char) RTS; + + /* init tx_stop with CTS */ + _tx_stop = ( (*MDSR & CTS) ? 0 : 1); + + set_vector(_catchUARTint, UART_ISR_LEVEL+24, 0); + + 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 +) +{ + if ((char *)(((int)rcv.in+1) & ((int)BUFFER_LENGTH-1))== rcv.out) + return(FALSE); + else + return(TRUE); +} + +/* + * 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 ] ); + } + + rw_args->bytes_moved = maximum; + return 0; +} + +/* + * 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/libbsp/m68k/efi68k/include/16550.h b/c/src/lib/libbsp/m68k/efi68k/include/16550.h new file mode 100644 index 0000000000..d13b5a1fc7 --- /dev/null +++ b/c/src/lib/libbsp/m68k/efi68k/include/16550.h @@ -0,0 +1,120 @@ +/* + *------------------------------------------------------------------- + * + * 16550 -- header file for National Semiconducor's 16550 UART + * + * This file has been created by John S. Gwynne for the efi68k + * project. + * + * Redistribution and use in source and binary forms are permitted + * provided that the following conditions are met: + * 1. Redistribution of source code and documentation must retain + * the above authorship, this list of conditions and the + * following disclaimer. + * 2. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * This software is provided "AS IS" without warranty of any kind, + * either expressed or implied, including, but not limited to, the + * implied warranties of merchantability, title and fitness for a + * particular purpose. + * + *------------------------------------------------------------------ + * + * $Id$ + */ + +#ifndef _16550_H_ +#define _16550_H_ + +/* base address is the physical location of register 0 */ +#define UART_BASE_ADDRESS 0x0400001 + +/* definitions of register addresses and associate bits */ + +#define RBR (volatile unsigned char * const)(0*2+UART_BASE_ADDRESS) + /* Receiver Buffer Register (w/DLAB=0)*/ + /* 8-bit data */ + +#define THR (volatile unsigned char * const)(0*2+UART_BASE_ADDRESS) + /* Transmitter Holding Register (w/DLAB=0) */ + /* 8-bit data */ + +#define DLL (volatile unsigned char * const)(0*2+UART_BASE_ADDRESS) + /* Divisor Latch (LS) (w/DLAB=1) */ + /* LSB of Divisor */ + +#define DLM (volatile unsigned char * const)(1*2+UART_BASE_ADDRESS) + /* Divisor Latch (MS) (w/DLAB=1) */ + /* MSB of Divisor */ + +#define IER (volatile unsigned char * const)(1*2+UART_BASE_ADDRESS) + /* Interrupt Enable Register (w/DLAB=0) */ +#define ERBFI 0x01 /* Enable Recv Data Available Interrupt */ +#define ETBEI 0x02 /* Enable Trans Holding Reg Empty Inter */ +#define ELSI 0x04 /* Enable Recv Line Status Interrupt */ +#define EDSSI 0x08 /* Enable Modem Status Interrupt */ + +#define IIR (volatile unsigned char * const)(2*2+UART_BASE_ADDRESS) + /* Interrupt Ident Register (read only) */ +#define NIP 0x01 /* No Interrupt Pending */ +#define IID_MASK 0x0e /* Interrupt ID mask */ +#define FE_MASK 0xc0 /* FIFO's Enabled */ + +#define FCR (volatile unsigned char * const)(2*2+UART_BASE_ADDRESS) + /* FIFO Control Register (write only) */ +#define FIFO_E 0x01 /* FIFO Enable */ +#define RFR 0x02 /* RCVR FIFO Reset */ +#define XFR 0x04 /* XMIT FIFO Reset */ +#define DMAMS 0x08 /* DMA Mode Select */ +#define RCVRTG_MASK 0xC0 /* RCVR Triger MSBit/LSBit */ + +#define LCR (volatile unsigned char * const)(3*2+UART_BASE_ADDRESS) + /* Line Control Register */ +#define WLS_MASK 0x03 /* Word Legth Select Mask */ +#define WL_5 0x00 /* 5 bits */ +#define WL_6 0x01 /* 6 bits */ +#define WL_7 0x02 /* 7 bits */ +#define WL_8 0x03 /* 8 bits */ +#define NSB 0x04 /* Number of Stop Bits (set is 2/1.5) */ +#define PEN 0x08 /* Parity Enable */ +#define EPS 0x10 /* Even Parity Select */ +#define STP 0x20 /* Stick Parity */ +#define SETBK 0x40 /* Set Break */ +#define DLAB 0x80 /* Divisor Latch Access Bit */ + +#define MCR (volatile unsigned char * const)(4*2+UART_BASE_ADDRESS) + /* Modem Control Register */ +#define DTR 0x01 /* Data Terminal Ready */ +#define RTS 0x02 /* Request to Send */ +#define OUT1 0x04 /* Out 1 */ +#define OUT2 0x08 /* Out 2 */ +#define LOOP 0x10 /* Loop */ + +#define LSR (volatile unsigned char * const)(5*2+UART_BASE_ADDRESS) + /* Line Status Register */ +#define DR 0x01 /* Data Ready */ +#define OE 0x02 /* Overrun error */ +#define PE 0x04 /* Parity error */ +#define FE 0x08 /* Framing error */ +#define BI 0x10 /* Break Interrupt */ +#define THRE 0x20 /* Transmitter Holding Register */ +#define TEMT 0x40 /* Transmitter Empty */ +#define RCVFIE 0x80 /* Recv FIFO Error */ + +#define MDSR (volatile unsigned char * const)(6*2+UART_BASE_ADDRESS) + /* Modem Status Register */ +#define DCTS 0x01 /* Delta Clear to Send */ +#define DDSR 0x02 /* Delta Data Set Ready */ +#define TERI 0x04 /* Trailing Edge Ring Indicator */ +#define DDCD 0x08 /* Delta Data Carrier Detect */ +#define CTS 0x10 /* Clear to Send */ +#define DSR 0x20 /* Data Set Ready */ +#define RI 0x40 /* Ring Indicator */ +#define DCD 0x80 /* Data Carrier Detect */ + +#define SCR (volatile unsigned char * const)(7*2+UART_BASE_ADDRESS) + /* Scratch Register */ + /* 8-bit register */ +#endif diff --git a/c/src/lib/libbsp/m68k/efi68k/include/DP8570A.h b/c/src/lib/libbsp/m68k/efi68k/include/DP8570A.h new file mode 100644 index 0000000000..7409d489ce --- /dev/null +++ b/c/src/lib/libbsp/m68k/efi68k/include/DP8570A.h @@ -0,0 +1,285 @@ +/* + *------------------------------------------------------------------- + * + * DP8570A -- header file for National Semiconducor's DP8570A TCP + * + * This file has been created by John S. Gwynne for the efi68k + * project. + * + * Redistribution and use in source and binary forms are permitted + * provided that the following conditions are met: + * 1. Redistribution of source code and documentation must retain + * the above authorship, this list of conditions and the + * following disclaimer. + * 2. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * This software is provided "AS IS" without warranty of any kind, + * either expressed or implied, including, but not limited to, the + * implied warranties of merchantability, title and fitness for a + * particular purpose. + * + *------------------------------------------------------------------ + * + * $Id$ + */ + +#ifndef _DP8570A_H_ +#define _DP8570A_H_ + +/* base address is the physical location of register 0 */ +#define TCP_BASE_ADDRESS 0x0600001 + + +/* definitions of register addresses and associate bits */ + +/* ********************************************************* */ +/* Control Registers */ +/* ********************************************************* */ + +/* REMEMBER: if you are in an interrupt routine, you must + reset RS and PS of MSR to the value they had on entry + to the ISR before exiting */ + +#define MSR (volatile unsigned char * const)(0x00*2+TCP_BASE_ADDRESS) + /* Main Status Register */ +#define INT 0x01 /* Interrupt Status */ +#define PF 0x02 /* Power Fail Interrupt */ +#define PER 0x04 /* Period Interrupt */ +#define AL 0x08 /* Alarm Interrupt */ +#define T0 0x10 /* Timer 0 Interrupt */ +#define T1 0x20 /* Timer 1 Interrupt */ +#define RS 0x40 /* Register Select Bit */ +#define PS 0x80 /* Page Select Bit */ + +#define T0CR (volatile unsigned char * const)(0x01*2+TCP_BASE_ADDRESS) + /* Timer 0 Control Register */ +#define T1CR (volatile unsigned char * const)(0x02*2+TCP_BASE_ADDRESS) + /* Timer 1 Control Register */ +#define TSS 0x01 /* Timer Start/!Stop */ +#define M0 0x02 /* Mode Select */ +#define M1 0x04 /* Mode Select */ +#define C0 0x08 /* Input Clock Select */ +#define C1 0x10 /* Input Clock Select */ +#define C2 0x20 /* Input Clock Select */ +#define RD 0x40 /* Timer Read */ +#define CHG 0x80 /* Count Hold/Gate */ + +#define PFR (volatile unsigned char * const)(0x03*2+TCP_BASE_ADDRESS) + /* Periodic Flag Register */ +#define R_1MIN 0x01 /* Minute Flage */ +#define R_10S 0x02 /* 10 Second Flag */ +#define R_1S 0x04 /* Second Flag */ +#define R_100MS 0x08 /* 100 Millisec Flag */ +#define R_10MS 0x10 /* 10 Millisec Flag */ +#define R_1MS 0x20 /* 1 Millisec Flag */ +#define OSF 0x40 /* Oscillator Failed/Single Supply */ +#define TMODE 0x80 /* Test Mode Enable */ + +#define IRR (volatile unsigned char * const)(0x04*2+TCP_BASE_ADDRESS) + /* Interrupt Routing Register */ +#define PF_R 0x01 /* Power Fail Route */ +#define PR_R 0x02 /* Periodic Route */ +#define AL_R 0x04 /* Alarm Route */ +#define T0_R 0x08 /* Timer 0 Route */ +#define T1_R 0x10 /* Timer 1 Route */ +#define PFD 0x20 /* PF Delay Enable */ +#define LBF 0x40 /* Low Battery Flag */ +#define TMSE 0x80 /* Time Save Enable */ + +#define RTMR (volatile unsigned char * const)(0x01*2+TCP_BASE_ADDRESS) + /* Real Time Mode Register */ +#define LY0 0x01 /* Leap Year LSB */ +#define LY1 0x02 /* Leap Year MSB */ +#define H12 0x04 /* 12/!24 Hour Mode */ +#define CSS 0x08 /* Clock Start/!Stop */ +#define IPF 0x10 /* Interrupt PF Operation */ +#define TPF 0x20 /* Timer PF Operation */ +#define XT0 0x40 /* Crystal Frequency LSB */ +#define XT1 0x80 /* Crystal Frequency MSB */ + +#define OMR (volatile unsigned char * const)(0x02*2+TCP_BASE_ADDRESS) + /* Output Mode Register */ +#define TH 0x01 /* T1 Active Hi/!Low */ +#define TP 0x02 /* T1 Push Pull/!Open Drain */ +#define IH 0x04 /* INTR Active Hi/!Low */ +#define IP 0x08 /* INTR Push Pull/!Open Drain */ +#define MH 0x10 /* MFO Active Hi/!Low */ +#define MP 0x20 /* MFO Push Pull/!Open Drain */ +#define MT 0x40 /* MFO Pin as Timer 0 */ +#define MO 0x80 /* MFO Pin as Oscillator */ + +#define ICR0 (volatile unsigned char * const)(0x03*2+TCP_BASE_ADDRESS) + /* Interrupt control Register 0 */ +#define ME 0x01 /* Minutes Enable */ +#define TSE 0x02 /* 10 Second Enable */ +#define SE 0x04 /* Seconds Enable */ +#define HME 0x08 /* 100 Millisec Enable */ +#define TME 0x10 /* 10 Millisec Enable */ +#define OME 0x20 /* Millisec Enable */ +#define T0E 0x40 /* Timer 0 Enable */ +#define T1E 0x80 /* Timer 1 Enable */ + +#define ICR1 (volatile unsigned char * const)(0x04*2+TCP_BASE_ADDRESS) + /* Interrupt control Register 1 */ +#define SCE 0x01 /* Second Compare Enable */ +#define MNE 0x02 /* Minute Compare Enable */ +#define HRE 0x04 /* Hour Compare Enable */ +#define DOME 0x08 /* Day of Month Compare Enable */ +#define MOE 0x10 /* Month Compare Enable */ +#define DOWE 0x20 /* Day of Week Compare Enable */ +#define ALE 0x40 /* Alarm Interrupt Enable */ +#define PFE 0x80 /* Power Fail Interrupt Enable */ + + + +/* ********************************************************* */ +/* Counters: Clock and Calendar (data is stored in BCD) */ +/* ********************************************************* */ +#define HOFS (volatile unsigned char * const)(0x05*2+TCP_BASE_ADDRESS) + /* Hundredth of Seconds */ +#define SEC (volatile unsigned char * const)(0x06*2+TCP_BASE_ADDRESS) + /* Seconds */ +#define MIN (volatile unsigned char * const)(0x07*2+TCP_BASE_ADDRESS) + /* Minutes */ +#define HRS (volatile unsigned char * const)(0x08*2+TCP_BASE_ADDRESS) + /* Hours */ +#define DOM (volatile unsigned char * const)(0x09*2+TCP_BASE_ADDRESS) + /* Day of Month */ +#define MON (volatile unsigned char * const)(0x0a*2+TCP_BASE_ADDRESS) + /* Month */ +#define YR (volatile unsigned char * const)(0x0b*2+TCP_BASE_ADDRESS) + /* Year */ +#define JD_LSB (volatile unsigned char * const)(0x0c*2+TCP_BASE_ADDRESS) + /* Julian Date (LSB) */ +#define JD_MSM (volatile unsigned char * const)(0x0d*2+TCP_BASE_ADDRESS) + /* Julian Date (MSB) */ +#define DOW (volatile unsigned char * const)(0x0e*2+TCP_BASE_ADDRESS) + /* Day of week */ + + +/* ********************************************************* */ +/* Timer Data Registers */ +/* ********************************************************* */ +#define T0_LSB (volatile unsigned char * const)(0x0f*2+TCP_BASE_ADDRESS) + /* Timer 0 LSB */ +#define T0_MSB (volatile unsigned char * const)(0x10*2+TCP_BASE_ADDRESS) + /* Timer 0 MSB */ +#define T1_LSB (volatile unsigned char * const)(0x11*2+TCP_BASE_ADDRESS) + /* Timer 1 LSB */ +#define T1_MSB (volatile unsigned char * const)(0x12*2+TCP_BASE_ADDRESS) + /* Timer 1 MSB */ + + +/* ********************************************************* */ +/* Timer Compare RAM */ +/* ********************************************************* */ +#define TC_SEC (volatile unsigned char * const)(0x13*2+TCP_BASE_ADDRESS) + /* Seconds Compare RAM */ +#define TC_MIN (volatile unsigned char * const)(0x14*2+TCP_BASE_ADDRESS) + /* Minutes Compare RAM */ +#define TC_HRS (volatile unsigned char * const)(0x15*2+TCP_BASE_ADDRESS) + /* Hours Compare RAM */ +#define TC_DOM (volatile unsigned char * const)(0x16*2+TCP_BASE_ADDRESS) + /* Day of Month Compare RAM */ +#define TC_MON (volatile unsigned char * const)(0x17*2+TCP_BASE_ADDRESS) + /* Month Compare RAM */ +#define TC_DOW (volatile unsigned char * const)(0x18*2+TCP_BASE_ADDRESS) + /* Day of Week Compare RAM */ + + +/* ********************************************************* */ +/* Time Save RAM */ +/* ********************************************************* */ +#define S_SEC (volatile unsigned char * const)(0x19*2+TCP_BASE_ADDRESS) + /* Seconds Save RAM */ +#define S_MIN (volatile unsigned char * const)(0x1a*2+TCP_BASE_ADDRESS) + /* Minutes Save RAM */ +#define S_HRS (volatile unsigned char * const)(0x1b*2+TCP_BASE_ADDRESS) + /* Hours Save RAM */ +#define S_DOM (volatile unsigned char * const)(0x1c*2+TCP_BASE_ADDRESS) + /* Day of Month Save RAM */ +#define S_MON (volatile unsigned char * const)(0x1d*2+TCP_BASE_ADDRESS) + /* Month Save RAM */ + + +/* ********************************************************* */ +/* Miscellaneous Registers */ +/* ********************************************************* */ + /* rem: 0x1e is general purpose RAM */ +#define TMR (volatile unsigned char * const)(0x1F*2+TCP_BASE_ADDRESS) + /* RAM/Test Mode Register */ + + + +/* ********************************************************* */ +/* RAM allocation */ +/* ********************************************************* */ +#define RAM_OSC_FAIL (volatile unsigned char * const)(0x01*2+TCP_BASE_ADDRESS) + /* 1: osc. failed time lost */ +#define RAM_POWERUP (volatile unsigned char * const)(0x02*2+TCP_BASE_ADDRESS) + /* 1: power was removed and the applied + before last TCP init */ +#define RAM_LOWBAT (volatile unsigned char * const)(0x03*2+TCP_BASE_ADDRESS) + /* 1: battery voltage is low (2.2V) */ + /* not valid in single supply mode */ +#define RAM_SINGLE_SUP (volatile unsigned char * const)(0x04*2+TCP_BASE_ADDRESS) + /* 1: single supply mode */ + /* note: single supply mode will be + selected when no backup battery is + present and/or the first time the + system is booted after the loss of + backup battery voltage. */ +#define RAM_TCP_FAILURE (volatile unsigned char * const)(0x05*2+TCP_BASE_ADDRESS) + /* 1: TCP failed to start oscillating */ + + +/* ********************************************************* */ +/* TCP data structures */ +/* ********************************************************* */ + +struct clock_counters { + unsigned char hofs; + unsigned char d0; /* the dx's are place holders since */ + unsigned char sec; /* the TCP is addressable only on */ + unsigned char d1; /* odd addresses. */ + unsigned char min; + unsigned char d2; + unsigned char hrs; + unsigned char d3; + unsigned char dom; + unsigned char d4; + unsigned char mon; + unsigned char d5; + unsigned char yr; + unsigned char d6; + unsigned char jd0; + unsigned char d7; + unsigned char jd1; + unsigned char d8; + unsigned char dow; +}; + +extern struct clock_ram * const tcp_power_up; + +struct clock_ram { + unsigned char sec; + unsigned char d0; /* the dx's are place holders since */ + unsigned char min; /* the TCP is addressable only on */ + unsigned char d1; /* odd addresses. */ + unsigned char hrs; + unsigned char d2; + unsigned char dom; + unsigned char d3; + unsigned char mon; +}; + +extern struct clock_ram * const tcp_power_up; +extern struct clock_ram * const tcp_power_down; +extern struct clock_counters * const tcp_clock; +extern struct clock_ram * const tcp_save_ram; + +void tcp_init(void); + +#endif /* _DP8570A_H_ */ diff --git a/c/src/lib/libbsp/m68k/efi68k/include/bsp.h b/c/src/lib/libbsp/m68k/efi68k/include/bsp.h new file mode 100644 index 0000000000..988383c0d1 --- /dev/null +++ b/c/src/lib/libbsp/m68k/efi68k/include/bsp.h @@ -0,0 +1,153 @@ +/* bsp.h + * + * This include file contains all efi68k board IO definitions. + * + * 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$ + */ + +#ifndef __EFI68K_BSP_h +#define __EFI68K_BSP_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include +#include +#include <16550.h> + +/* + * Define the time limits for RTEMS Test Suite test durations. + * Long test and short test duration limits are provided. These + * values are in seconds and need to be converted to ticks for the + * application. + * + */ + +#define MAX_LONG_TEST_DURATION 300 /* 5 minutes = 300 seconds */ +#define MAX_SHORT_TEST_DURATION 3 /* 3 seconds */ + +/* + * Define the interrupt mechanism for Time Test 27 + */ + +/* XXX - JRS - I want to compile the tmtests */ + +#define MUST_WAIT_FOR_INTERRUPT 1 + +#define Install_tm27_vector( handler ) + +#define Cause_tm27_intr() + +#define Clear_tm27_intr() + +#define Lower_tm27_intr() + +/* + * Simple spin delay in microsecond units for device drivers. + * This is very dependent on the clock speed of the target. + */ + +#define delay( microseconds ) \ + { register rtems_unsigned32 _delay=(microseconds); \ + register rtems_unsigned32 _tmp=123; \ + asm volatile( "0: \ + nbcd %0 ; \ + nbcd %0 ; \ + dbf %1,0b" \ + : "=d" (_tmp), "=d" (_delay) \ + : "0" (_tmp), "1" (_delay) ); \ + } + +/* macros */ + +#define RAM_START 0x200000 +#define RAM_END 0x240000 + +#define RAW_PUTS(str) \ + { register char *ptr = str; \ + while (*ptr) outbyte(*ptr++); \ + } + +#define RAW_PUTI(n) { \ + register int i, j; \ + \ + RAW_PUTS("0x"); \ + for (i=28;i>=0;i -= 4) { \ + j = (n>>i) & 0xf; \ + outbyte( (j>9 ? j-10+'a' : j+'0') ); \ + } \ + } + +/* miscellaneous stuff assumed to exist */ + +extern rtems_configuration_table BSP_Configuration; + +extern m68k_isr_entry M68Kvec[]; /* vector table address */ + +extern int stack_size; + +extern int stack_start; + +extern rtems_unsigned32 Timer_interrupts; + +/* + * Device Driver Table Entries + */ + +/* + * NOTE: Use the standard Console driver entry + */ + +/* + * NOTE: Use the standard Clock driver entry + */ + +/* + * How many libio files we want + */ + +#define BSP_LIBIO_MAX_FDS 20 + +/* functions */ + +void bsp_cleanup( void ); + +m68k_isr_entry set_vector( + rtems_isr_entry handler, + rtems_vector_number vector, + int type +); + +void console_init(void); + +void watch_dog_init(void); + +void tcp_init(void); + +void Spurious_Initialize(void); + +void _UART_flush(void); + +void Clock_exit(void); + +void outbyte(char); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/c/src/lib/libbsp/m68k/efi68k/include/coverhd.h b/c/src/lib/libbsp/m68k/efi68k/include/coverhd.h new file mode 100644 index 0000000000..671f20d197 --- /dev/null +++ b/c/src/lib/libbsp/m68k/efi68k/include/coverhd.h @@ -0,0 +1,106 @@ +/* coverhd.h + * + * This include file has defines to represent the overhead associated + * with calling a particular directive from C. These are used in the + * Timing Test Suite to ignore the overhead required to pass arguments + * to directives. On some CPUs and/or target boards, this overhead + * is significant and makes it difficult to distinguish internal + * RTEMS execution time from that used to call the directive. + * This file should be updated after running the C overhead timing + * test. Once this update has been performed, the RTEMS Time Test + * Suite should be rebuilt to account for these overhead times in the + * timing results. + * + * NOTE: If these are all zero, then the times reported include all + * all calling overhead including passing of arguments. + * + * 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$ + */ + +#ifndef __COVERHD_h +#define __COVERHD_h + +#define CALLING_OVERHEAD_INITIALIZE_EXECUTIVE 0 +#define CALLING_OVERHEAD_SHUTDOWN_EXECUTIVE 0 +#define CALLING_OVERHEAD_TASK_CREATE 0 +#define CALLING_OVERHEAD_TASK_IDENT 0 +#define CALLING_OVERHEAD_TASK_START 0 +#define CALLING_OVERHEAD_TASK_RESTART 0 +#define CALLING_OVERHEAD_TASK_DELETE 0 +#define CALLING_OVERHEAD_TASK_SUSPEND 0 +#define CALLING_OVERHEAD_TASK_RESUME 0 +#define CALLING_OVERHEAD_TASK_SET_PRIORITY 0 +#define CALLING_OVERHEAD_TASK_MODE 0 +#define CALLING_OVERHEAD_TASK_GET_NOTE 0 +#define CALLING_OVERHEAD_TASK_SET_NOTE 0 +#define CALLING_OVERHEAD_TASK_WAKE_WHEN 0 +#define CALLING_OVERHEAD_TASK_WAKE_AFTER 0 +#define CALLING_OVERHEAD_INTERRUPT_CATCH 0 +#define CALLING_OVERHEAD_CLOCK_GET 0 +#define CALLING_OVERHEAD_CLOCK_SET 0 +#define CALLING_OVERHEAD_CLOCK_TICK 0 + +#define CALLING_OVERHEAD_TIMER_CREATE 0 +#define CALLING_OVERHEAD_TIMER_IDENT 0 +#define CALLING_OVERHEAD_TIMER_DELETE 0 +#define CALLING_OVERHEAD_TIMER_FIRE_AFTER 0 +#define CALLING_OVERHEAD_TIMER_FIRE_WHEN 0 +#define CALLING_OVERHEAD_TIMER_RESET 0 +#define CALLING_OVERHEAD_TIMER_CANCEL 0 +#define CALLING_OVERHEAD_SEMAPHORE_CREATE 0 +#define CALLING_OVERHEAD_SEMAPHORE_IDENT 0 +#define CALLING_OVERHEAD_SEMAPHORE_DELETE 0 +#define CALLING_OVERHEAD_SEMAPHORE_OBTAIN 0 +#define CALLING_OVERHEAD_SEMAPHORE_RELEASE 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_CREATE 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_IDENT 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_DELETE 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_SEND 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_URGENT 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_BROADCAST 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_RECEIVE 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_FLUSH 0 + +#define CALLING_OVERHEAD_EVENT_SEND 0 +#define CALLING_OVERHEAD_EVENT_RECEIVE 0 +#define CALLING_OVERHEAD_SIGNAL_CATCH 0 +#define CALLING_OVERHEAD_SIGNAL_SEND 0 +#define CALLING_OVERHEAD_PARTITION_CREATE 0 +#define CALLING_OVERHEAD_PARTITION_IDENT 0 +#define CALLING_OVERHEAD_PARTITION_DELETE 0 +#define CALLING_OVERHEAD_PARTITION_GET_BUFFER 0 +#define CALLING_OVERHEAD_PARTITION_RETURN_BUFFER 0 +#define CALLING_OVERHEAD_REGION_CREATE 0 +#define CALLING_OVERHEAD_REGION_IDENT 0 +#define CALLING_OVERHEAD_REGION_DELETE 0 +#define CALLING_OVERHEAD_REGION_GET_SEGMENT 0 +#define CALLING_OVERHEAD_REGION_RETURN_SEGMENT 0 +#define CALLING_OVERHEAD_PORT_CREATE 0 +#define CALLING_OVERHEAD_PORT_IDENT 0 +#define CALLING_OVERHEAD_PORT_DELETE 0 +#define CALLING_OVERHEAD_PORT_EXTERNAL_TO_INTERNAL 0 +#define CALLING_OVERHEAD_PORT_INTERNAL_TO_EXTERNAL 0 + +#define CALLING_OVERHEAD_IO_INITIALIZE 0 +#define CALLING_OVERHEAD_IO_OPEN 0 +#define CALLING_OVERHEAD_IO_CLOSE 0 +#define CALLING_OVERHEAD_IO_READ 0 +#define CALLING_OVERHEAD_IO_WRITE 0 +#define CALLING_OVERHEAD_IO_CONTROL 0 +#define CALLING_OVERHEAD_FATAL_ERROR_OCCURRED 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_CREATE 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_IDENT 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_DELETE 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_CANCEL 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_PERIOD 0 +#define CALLING_OVERHEAD_MULTIPROCESSING_ANNOUNCE 0 + +#endif diff --git a/c/src/lib/libbsp/m68k/efi68k/include/efi68k.h b/c/src/lib/libbsp/m68k/efi68k/include/efi68k.h new file mode 100644 index 0000000000..398dbf2fb4 --- /dev/null +++ b/c/src/lib/libbsp/m68k/efi68k/include/efi68k.h @@ -0,0 +1,21 @@ +/* efi68k.h + * + * $Id$ + */ + +#ifndef _EFI68k_H_ +#define _EFI68k_H_ + + +/* interrupt levels */ +#define WD_ISR_LEVEL 1 +#define TCP_ISR_LEVEL 4 +#define UART_ISR_LEVEL 6 +#define INTR7 7 + + +/* macro/function definitions */ +static void reboot(void) __attribute__ ((noreturn)); +__inline__ static void reboot(void) {asm("trap #15");} + +#endif /* _EFI68k_H_ */ diff --git a/c/src/lib/libbsp/m68k/efi68k/spurious/spinit.c b/c/src/lib/libbsp/m68k/efi68k/spurious/spinit.c new file mode 100644 index 0000000000..2b12880c8d --- /dev/null +++ b/c/src/lib/libbsp/m68k/efi68k/spurious/spinit.c @@ -0,0 +1,85 @@ +/* Spurious_driver + * + * This routine installs spurious interrupt handlers for the efi68k. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993. + * On-Line Applications Research Corporation (OAR). + * + * 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 +#include + +const char * const _Spurious_Error_[] = {"Reset","Bus Error","Address Error", + "Illegal Instruction","Zero Division","CHK, CHK2 Instruction", + "TRAPcc, TRAPV Instruction","Privilege Violation","Trace", + "Line 1010 Emulation","Line 1111 Emulation","Hardware Breakpoint", + "Coprocessor Protocal Violation", + "Format Error ans Uninitialized Interrupt","Unassigned", + "Spurious Interrupt","AVec1","AVec2","AVec3","AVec4","AVec5","AVec6", + "AVec7","Trap Instruction","Debug","Reboot","Reserved Coprocessor", + "Reserved Unassigned","User Defined"}; + +rtems_isr Spurious_Isr( + rtems_vector_number vector +) +{ + int sp = 0; + const char * const VectDescrip[] = { + _Spurious_Error_[0], _Spurious_Error_[0], _Spurious_Error_[1], + _Spurious_Error_[2], _Spurious_Error_[3], _Spurious_Error_[4], + _Spurious_Error_[5], _Spurious_Error_[6], _Spurious_Error_[7], + _Spurious_Error_[8], _Spurious_Error_[9], _Spurious_Error_[10], + _Spurious_Error_[11], _Spurious_Error_[12], _Spurious_Error_[13], + _Spurious_Error_[13], _Spurious_Error_[14], _Spurious_Error_[14], + _Spurious_Error_[14], _Spurious_Error_[14], _Spurious_Error_[14], + _Spurious_Error_[14], _Spurious_Error_[14], _Spurious_Error_[14], + _Spurious_Error_[15], _Spurious_Error_[16], _Spurious_Error_[17], + _Spurious_Error_[18], _Spurious_Error_[19], _Spurious_Error_[20], + _Spurious_Error_[21], _Spurious_Error_[22], _Spurious_Error_[23], + _Spurious_Error_[24], _Spurious_Error_[23], _Spurious_Error_[23], + _Spurious_Error_[23], _Spurious_Error_[23], _Spurious_Error_[23], + _Spurious_Error_[23], _Spurious_Error_[23], _Spurious_Error_[23], + _Spurious_Error_[23], _Spurious_Error_[23], _Spurious_Error_[23], + _Spurious_Error_[23], _Spurious_Error_[23], _Spurious_Error_[25], + _Spurious_Error_[26], _Spurious_Error_[26], _Spurious_Error_[26], + _Spurious_Error_[26], _Spurious_Error_[26], _Spurious_Error_[26], + _Spurious_Error_[26], _Spurious_Error_[26], _Spurious_Error_[26], + _Spurious_Error_[26], _Spurious_Error_[26], _Spurious_Error_[27], + _Spurious_Error_[27], _Spurious_Error_[27], _Spurious_Error_[27], + _Spurious_Error_[27], _Spurious_Error_[28]}; + + asm volatile ( "movea.l %%sp,%0 " : "=a" (sp) : "0" (sp) ); + + _CPU_ISR_Set_level( 7 ); + _UART_flush(); + + RAW_PUTS("\n\rRTEMS: Spurious interrupt: "); + RAW_PUTS((char *)VectDescrip[( (vector>64) ? 64 : vector )]); + RAW_PUTS("\n\rRTEMS: Vector: "); + RAW_PUTI(vector); + RAW_PUTS(" sp: "); + RAW_PUTI(sp); + RAW_PUTS("\n\r"); + + bsp_cleanup(); + + for(;;); +} + +void Spurious_Initialize(void) +{ + rtems_vector_number vector; + + for ( vector = 0x0 ; vector <= 0xFF ; vector++ ) + (void) set_vector( Spurious_Isr, vector, 1 ); +} diff --git a/c/src/lib/libbsp/m68k/efi68k/startup/bspclean.c b/c/src/lib/libbsp/m68k/efi68k/startup/bspclean.c new file mode 100644 index 0000000000..34a57b6b68 --- /dev/null +++ b/c/src/lib/libbsp/m68k/efi68k/startup/bspclean.c @@ -0,0 +1,28 @@ +/* bsp_cleanup() + * + * This routine cleans up in the sense that it places the board + * in a safe state and flushes the I/O buffers before exiting. + * + * INPUT: NONE + * + * OUTPUT: NONE + * + * 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 + +void bsp_cleanup(void) +{ + /* interrupt driven stdio must be flushed */ + _CPU_ISR_Set_level( 7 ); + _UART_flush(); +} diff --git a/c/src/lib/libbsp/m68k/efi68k/startup/bspstart.c b/c/src/lib/libbsp/m68k/efi68k/startup/bspstart.c new file mode 100644 index 0000000000..e08f78baff --- /dev/null +++ b/c/src/lib/libbsp/m68k/efi68k/startup/bspstart.c @@ -0,0 +1,230 @@ +#define STACK_CHECKER_ON +/* bsp_start() + * + * This routine starts the application. It includes application, + * board, and monitor specific initialization and configuration. + * The generic CPU dependent initialization has been performed + * before this routine is invoked. + * + * INPUT: NONE + * + * OUTPUT: NONE + * + * 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 +#include +#include +#include + +#include +#include + +#ifdef STACK_CHECKER_ON +#include +#endif + +/* + * The original table from the application and our copy of it with + * some changes. + */ + +extern rtems_configuration_table Configuration; +rtems_configuration_table BSP_Configuration; + +rtems_cpu_table Cpu_table; + +char *rtems_progname; + +rtems_unsigned32 Timer_interrupts; + +/* extern void set_debug_traps(void); */ +/* extern void breakpoint(void); */ + +/* Initialize whatever libc we are using + * called from postdriver hook + */ + +void bsp_libc_init() +{ + extern int end; + rtems_unsigned32 heap_start; + + heap_start = (rtems_unsigned32) &end; + if (heap_start & (CPU_ALIGNMENT-1)) + heap_start = (heap_start + CPU_ALIGNMENT) & ~(CPU_ALIGNMENT-1); + + RTEMS_Malloc_Initialize((void *) heap_start, 64 * 1024, 0); + + /* + * Init the RTEMS libio facility to provide UNIX-like system + * calls for use by newlib (ie: provide __open, __close, etc) + * Uses malloc() to get area for the iops, so must be after malloc init + */ + + rtems_libio_init(); + + /* + * Set up for the libc handling. + */ + + if (BSP_Configuration.ticks_per_timeslice > 0) + libc_init(1); /* reentrant if possible */ + else + libc_init(0); /* non-reentrant */ + +} + +/* + * Function: bsp_pretasking_hook + * Created: 95/03/10 + * + * Description: + * BSP pretasking hook. Called just before drivers are initialized. + * Used to setup libc and install any BSP extensions. + * + * NOTES: + * Must not use libc (to do io) from here, since drivers are + * not yet initialized. + * + */ + +void +bsp_pretasking_hook(void) +{ + bsp_libc_init(); + +#ifdef STACK_CHECKER_ON + /* + * Initialize the stack bounds checker + * We can either turn it on here or from the app. + */ + + Stack_check_Initialize(); +#endif + +#ifdef RTEMS_DEBUG + rtems_debug_enable( RTEMS_DEBUG_ALL_MASK ); +#endif +} + + +/* + * After drivers are setup, register some "filenames" + * and open stdin, stdout, stderr files + * + * Newlib will automatically associate the files with these + * (it hardcodes the numbers) + */ + +void +bsp_postdriver_hook(void) +{ + int stdin_fd, stdout_fd, stderr_fd; + + if ((stdin_fd = __open("/dev/console", O_RDONLY, 0)) == -1) + rtems_fatal_error_occurred('STD0'); + + if ((stdout_fd = __open("/dev/console", O_WRONLY, 0)) == -1) + rtems_fatal_error_occurred('STD1'); + + if ((stderr_fd = __open("/dev/console", O_WRONLY, 0)) == -1) + rtems_fatal_error_occurred('STD2'); + + if ((stdin_fd != 0) || (stdout_fd != 1) || (stderr_fd != 2)) + rtems_fatal_error_occurred('STIO'); +} + +int main( + int argc, + char **argv, + char **environp +) +{ + void *vbr; + +/* set_debug_traps(); */ +/* breakpoint(); */ + + /* + * we only use a hook to get the C library initialized. + */ + + Cpu_table.pretasking_hook = bsp_pretasking_hook; /* init libc, etc. */ + + Cpu_table.predriver_hook = NULL; + + Cpu_table.postdriver_hook = bsp_postdriver_hook; + + Cpu_table.idle_task = NULL; /* do not override system IDLE task */ + + Cpu_table.do_zero_of_workspace = TRUE; + + m68k_get_vbr( vbr ); + Cpu_table.interrupt_vector_table = vbr; + + Cpu_table.interrupt_stack_size = 4096; + + Cpu_table.extra_system_initialization_stack = 0; + + /* + * Copy the table + */ + + BSP_Configuration = Configuration; + + BSP_Configuration.work_space_start = (void *) + (RAM_END - BSP_Configuration.work_space_size); + + if ((unsigned int)BSP_Configuration.work_space_start < + (unsigned int)((stack_start + stack_size) & 0xffffffc0) ) { + /* rtems_fatal_error_occurred can not be used before initalization */ + RAW_PUTS("\n\rRTEMS: Out of memory.\n\r"); + RAW_PUTS("RTEMS: Check RAM_END and the size of the work space.\n\r"); + goto exit; + } + + /* + * Add 1 region for Malloc in libc_low + */ + + BSP_Configuration.maximum_regions++; + + /* + * Add 1 extension for newlib libc + */ + +#ifdef RTEMS_NEWLIB + BSP_Configuration.maximum_extensions++; +#endif + + /* + * Add another extension if using the stack checker + */ + +#ifdef STACK_CHECKER_ON + BSP_Configuration.maximum_extensions++; +#endif + + rtems_initialize_executive( &BSP_Configuration, &Cpu_table ); + /* does not return */ + + /* Clock_exit is done as an atexit() function */ + +exit: + /* configure peripherals for safe exit */ + bsp_cleanup(); + + /* return like a "normal" subroutine to the monitor */ + return 0; +} + diff --git a/c/src/lib/libbsp/m68k/efi68k/startup/efi68k_tcp.c b/c/src/lib/libbsp/m68k/efi68k/startup/efi68k_tcp.c new file mode 100644 index 0000000000..9dd4836b25 --- /dev/null +++ b/c/src/lib/libbsp/m68k/efi68k/startup/efi68k_tcp.c @@ -0,0 +1,248 @@ +/* + *------------------------------------------------------------------- + * + * This file contains the subroutines necessary to initalize + * the DP8750A TCP on the efi68k board. + * + * This file has been created by John S. Gwynne for the efi68k + * project. + * + * Redistribution and use in source and binary forms are permitted + * provided that the following conditions are met: + * 1. Redistribution of source code and documentation must retain + * the above authorship, this list of conditions and the + * following disclaimer. + * 2. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * This software is provided "AS IS" without warranty of any kind, + * either expressed or implied, including, but not limited to, the + * implied warranties of merchantability, title and fitness for a + * particular purpose. + * + *------------------------------------------------------------------ + * + * $Id$ + */ + +#include + +/* define tcp struct pointers */ +struct clock_ram * const tcp_power_up = + (struct clock_ram * const)(0x16*2+TCP_BASE_ADDRESS); + +struct clock_ram * const tcp_power_down = + (struct clock_ram * const)(0x1b*2+TCP_BASE_ADDRESS); + +struct clock_counters * const tcp_clock = + (struct clock_counters * const)(0x05*2+TCP_BASE_ADDRESS); + +struct clock_ram * const tcp_save_ram = + (struct clock_ram * const)(0x19*2+TCP_BASE_ADDRESS); + +#define X_DELAY 300 /* time-out delay for crystal start */ +#define X1_DELAY 100000 + +void tcp_delay(int count) +{ + int i; + /* change latter to use a counter !!! */ + for (i=0;ihofs = 0; + tcp_clock->sec = 0; + tcp_clock->min = 0; + tcp_clock->hrs = 0; + tcp_clock->dom = 1; + tcp_clock->mon = 1; + tcp_clock->yr = 0x95; + tcp_clock->jd0 = 0x01; + tcp_clock->jd1 = 0; + tcp_clock->dow = 1; + *MSR = PS; + tcp_power_up->sec = 0; + tcp_power_up->min = 0; + tcp_power_up->hrs = 0; + tcp_power_up->dom = 0; + tcp_power_up->mon = 0; + tcp_power_down->sec = 0; + tcp_power_down->min = 0; + tcp_power_down->hrs = 0; + tcp_power_down->dom = 0; + tcp_power_down->mon = 0; + } else { + /* save for power-up test */ + *MSR = 0; + power_up = (*IRR & TMSE ? 0 : 1); + *MSR = PS; + *RAM_POWERUP = power_up; + + /* update tcp_power_up and tcp_power_down on power up */ + if (power_up) { + *MSR = 0; + do { + *PFR; + sec = tcp_clock->sec; + min = tcp_clock->min; + hrs = tcp_clock->hrs; + dom = tcp_clock->dom; + mon = tcp_clock->mon; + } while (*PFR & R_1S); + *MSR = PS; + tcp_power_up->sec = sec; + tcp_power_up->min = min; + tcp_power_up->hrs = hrs; + tcp_power_up->dom = dom; + tcp_power_up->mon = ( (((mon>>4)*10)+(mon&0xf))>12 ? 0 : mon ); + *MSR = 0; /* save ram is not running */ + sec = tcp_save_ram->sec; + min = tcp_save_ram->min; + hrs = tcp_save_ram->hrs; + dom = tcp_save_ram->dom; + mon = tcp_save_ram->mon; + *MSR = PS; + tcp_power_down->sec = sec; + tcp_power_down->min = min; + tcp_power_down->hrs = hrs; + tcp_power_down->dom = dom; + tcp_power_down->mon = ( (((mon>>4)*10)+(mon&0xf))>12 ? 0 : mon ); + } + } + + /* load interrupt routing reg. PF must be enabled to test + for low battery, but I route it to MFO to avoid any + potential problems */ + *MSR = 0; + *IRR = PF_R | TMSE; + + /* initialize the output mode register */ + *MSR = RS; + *OMR = IP | MP | MO; /* INTR active low and push/pull */ + + /* initialize interrupt control reg 0 */ + *MSR = RS; + *ICR0 = 0; /* disable all interrupts */ + + /* initialize interrupt control reg 1 */ + *MSR = RS; + *ICR1 = PFE; /* this also enables the low battery + detection circuit. */ + + /* I had trouble getting the tcp to be completely + flexabale to supply modes (i.e., automatically + selecting single or normal battery backup modes based + on inputs at power-up. If single supply mode is + selected, the low battery detect is disabled and the + low battery detect in normal mode does not seem to + detect when no battery is present at all. If normal + mode is selected and no battery is present, the + crystal will stop, but only if reset after + power-up. It would seem that after a power-up reset, + with no battery, the chip may automaticlly switch to + single supply mode which disables the low battery + detection circuit.) The following software tests + works for all permiatations of low batt, reset, + power-on reset, battery, no battery, battery on after + Vcc,.... *except* for battery switched on for the + first time before power up in which case the chip + will still be in single suppy mode till restarted (a + second call to tcp_init such as when the time is set + or a reboot.) The timer/clock itself should always + be completely functional regardless of the supply + mode. */ + + + /* initialize the real time mode register */ + /* note: write mode bits *before* CSS, then set CSS */ + *MSR = 0; /* clear roll-over */ + *PFR; + count=1; + for (i=0;i=X_DELAY) { + { + /* xtal didn't start; try single supply mode */ + *MSR = 0; /* single supply */ + *PFR = OSF; + *MSR = 0; /* clear roll-over */ + *PFR; + count=1; + for (i=0;i=X1_DELAY) { + /* xtal didn't start; fail tcp */ + *MSR = PS; + *RAM_TCP_FAILURE = 1; + *MSR = PS; + *RAM_SINGLE_SUP=1; + } else { + *MSR = PS; + *RAM_TCP_FAILURE = 0; + *MSR = PS; + *RAM_SINGLE_SUP=1; + } + } + } else { + *MSR = PS; + *RAM_TCP_FAILURE = 0; + *MSR = PS; + *RAM_SINGLE_SUP=0; + } + + /* wait for low battery detection circuit to stabalize */ + tcp_delay(1000); + + /* battery test */ + *MSR = 0; + low_bat = (*IRR & LBF ? 1 : 0 ); + *MSR = PS; + *RAM_LOWBAT = low_bat & !(*RAM_SINGLE_SUP); + + /* reset pending interrupts */ + *MSR = ( PER | AL | T0 | T1 ); + + /* resync the time save ram with the clock */ + tcp_save_ram->sec = 0; + tcp_save_ram->min = 0; + tcp_save_ram->hrs = 0; + tcp_save_ram->dom = 0; + tcp_save_ram->mon = 0; +} diff --git a/c/src/lib/libbsp/m68k/efi68k/startup/efi68k_wd.c b/c/src/lib/libbsp/m68k/efi68k/startup/efi68k_wd.c new file mode 100644 index 0000000000..0ad4d87b82 --- /dev/null +++ b/c/src/lib/libbsp/m68k/efi68k/startup/efi68k_wd.c @@ -0,0 +1,55 @@ +/* + *------------------------------------------------------------------- + * + * This file contains the subroutines necessary to initalize + * and maintain the MAX791 based watchdog timer used on efi68k + * + * This file has been created by John S. Gwynne for the efi68k + * project. + * + * Redistribution and use in source and binary forms are permitted + * provided that the following conditions are met: + * 1. Redistribution of source code and documentation must retain + * the above authorship, this list of conditions and the + * following disclaimer. + * 2. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * This software is provided "AS IS" without warranty of any kind, + * either expressed or implied, including, but not limited to, the + * implied warranties of merchantability, title and fitness for a + * particular purpose. + * + *------------------------------------------------------------------ + * + * $Id$ + */ +#include + +void wd_interrupt(void) { + /* toggle WDI of the MAX791. A more sophisticated routine + can be inserted into the exception table after booting. */ + + /* 3 changes guaranty a pulse independent of initial state */ + *MCR |= OUT1; + *MCR &= ~OUT1; + *MCR |= OUT1; +} + +/* _catchWDint is the interrupt front-end */ +extern void _catchWDint(); +asm(" .text + .align 2 + .globl _catchWDint +_catchWDint: + lea %sp@(4),%sp /* pop return address */ + moveml %d0-%d7/%a0-%a6,%sp@- /* save registers */ + jbsr wd_interrupt + moveml %sp@+,%d0-%d7/%a0-%a6 + rte + "); + +void watch_dog_init(void) { + set_vector(_catchWDint, WD_ISR_LEVEL+24, 0); +} diff --git a/c/src/lib/libbsp/m68k/efi68k/startup/linkcmds b/c/src/lib/libbsp/m68k/efi68k/startup/linkcmds new file mode 100644 index 0000000000..f34bafab92 --- /dev/null +++ b/c/src/lib/libbsp/m68k/efi68k/startup/linkcmds @@ -0,0 +1,108 @@ +/* linkcmds + * + * $Id$ + */ + +OUTPUT_ARCH(m68k) +__DYNAMIC = 0; + +/* + * The memory map looks like this: + * +--------------------+ <- low memory + * | .text | + * | etext | + * | ctor list | the ctor and dtor lists are for + * | dtor list | C++ support + * | _endtext | + * +--------------------+ + * | .data | initialized data goes here + * | _sdata | + * | _edata | + * +--------------------+ + * | .bss | + * | __bss_start | start of bss, cleared by crt0 + * | _end | start of heap, used by sbrk() + * +--------------------+ + * | heap space | + * | _ENDHEAP | + * | stack space | + * | __stack | top of stack + * +--------------------+ <- high memory + */ + + +/* + * User modifiable values: + * + * _VBR location of VBR table + */ + +MEMORY +{ + ram : ORIGIN = 0x203000, LENGTH = 256K +} + +_VBR = 0x200000; /* location of the VBR table (in RAM) */ +_copy_data_from_rom = 0; + +/* + * stick everything in ram (of course) + */ +SECTIONS +{ + .text : + { + CREATE_OBJECT_SYMBOLS + text_start = .; + _text_start = .; + *(.text) + etext = ALIGN(0x10); + _etext = .; + __CTOR_LIST__ = .; + LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2) + *(.ctors) + LONG(0) + __CTOR_END__ = .; + __DTOR_LIST__ = .; + LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2) + *(.dtors) + LONG(0) + __DTOR_END__ = .; + *(.lit) + *(.shdata) + _endtext = .; + } > ram + .data : + { + data_start = .; + _data_start = .; + _sdata = . ; + *(.data) + CONSTRUCTORS + edata = ALIGN(0x10); + _edata = .; + } > ram + .shbss : + { + *(.shbss) + } > ram + .bss : + { + __bss_start = ALIGN(0x8); + bss_start = .; + _bss_start = .; + *(.bss) + *(COMMON) + end = .; + _end = ALIGN(0x8); + __end = ALIGN(0x8); + } > ram + .stab . (NOLOAD) : + { + [ .stab ] + } + .stabstr . (NOLOAD) : + { + [ .stabstr ] + } +} diff --git a/c/src/lib/libbsp/m68k/efi68k/startup/m68k-stub.c b/c/src/lib/libbsp/m68k/efi68k/startup/m68k-stub.c new file mode 100644 index 0000000000..a37cd2dc83 --- /dev/null +++ b/c/src/lib/libbsp/m68k/efi68k/startup/m68k-stub.c @@ -0,0 +1,782 @@ +/* m68k-stub.c + * + * $Id$ + */ + +#include +#include + +m68k_isr_entry set_vector( + rtems_isr_entry handler, + rtems_vector_number vector, + int type +); + + +void (*exceptionHook)() = 0; + +void outbyte(char c); +char putDebugChar( char c) +{ + outbyte(c); + return c; +} + +char inbyte(void); +char getDebugChar(void) +{ + return inbyte(); +} + +void flush_i_cache(void) +{ + return; +} + +void *memset(void *p, int c, int n) +{ + register int i; + void *s=p; + + for (i=0;i 0 prints ill-formed commands in valid packets & checksum errors */ + +static const char hexchars[]="0123456789abcdef"; + +/* there are 180 bytes of registers on a 68020 w/68881 */ +/* many of the fpa registers are 12 byte (96 bit) registers */ +#define NUMREGBYTES 180 +enum regnames {D0,D1,D2,D3,D4,D5,D6,D7, + A0,A1,A2,A3,A4,A5,A6,A7, + PS,PC, + FP0,FP1,FP2,FP3,FP4,FP5,FP6,FP7, + FPCONTROL,FPSTATUS,FPIADDR + }; + + + +typedef struct FrameStruct +{ + struct FrameStruct *previous; + int exceptionPC; /* pc value when this frame created */ + int exceptionVector; /* cpu vector causing exception */ + short frameSize; /* size of cpu frame in words */ + short sr; /* for 68000, this not always sr */ + int pc; + short format; + int fsaveHeader; + int morejunk[0]; /* exception frame, fp save... */ +} Frame; + +#define FRAMESIZE 10 +int gdbFrameStack[FRAMESIZE]; +static Frame *lastFrame; + +/* + * these should not be static cuz they can be used outside this module + */ +int registers[NUMREGBYTES/4]; +int superStack; + +#define STACKSIZE 600 +int remcomStack[STACKSIZE/sizeof(int)]; +static int* stackPtr = &remcomStack[STACKSIZE/sizeof(int) - 1]; + +static ExceptionHook oldExceptionHook; + +#define SAVE_FP_REGS() +#define RESTORE_FP_REGS() + +void return_to_super(); +void return_to_user(); + +asm(" +.text +.align 2 +.globl return_to_super +return_to_super: + oriw #0x0700,%sr + movel registers+60,%sp /* get new stack pointer */ + movel lastFrame,%a0 /* get last frame info */ + bra return_to_any + +.globl return_to_user +return_to_user: + oriw #0x0700,%sr + movel registers+60,%a0 /* get usp */ + movel %a0,%usp /* set usp */ + movel superStack,%sp /* get original stack pointer */ + +return_to_any: + movel lastFrame,%a0 /* get last frame info */ + movel %a0@+,lastFrame /* link in previous frame */ + addql #8,%a0 /* skip over pc, vector#*/ + movew %a0@+,%d0 /* get # of words in cpu frame */ + addw %d0,%a0 /* point to end of data */ + addw %d0,%a0 /* point to end of data */ + movel %a0,%a1 +# +# copy the stack frame + subql #1,%d0 +copyUserLoop: + movew %a1@-,%sp@- + dbf %d0,copyUserLoop +"); + RESTORE_FP_REGS() + asm(" moveml registers,%d0-%d7/%a0-%a6"); + asm(" rte"); /* pop and go! */ + +#define DISABLE_INTERRUPTS() asm(" oriw #0x0700,%sr"); +#define BREAKPOINT() asm(" trap #1"); + +/* this function is called immediately when a level 7 interrupt occurs */ +/* if the previous interrupt level was 7 then we're already servicing */ +/* this interrupt and an rte is in order to return to the debugger. */ +/* For the 68000, the offset for sr is 6 due to the jsr return address */ +asm(" +.text +.align 2 +.globl _debug_level7 +_debug_level7: + movew %d0,%sp@-"); +asm(" movew %sp@(6),%d0"); + +asm(" andiw #0x700,%d0 + cmpiw #0x700,%d0 + beq already7 + movew %sp@+,%d0 + bra _catchException +already7: + movew %sp@+,%d0"); +asm(" lea %sp@(4),%sp"); /* pull off 68000 return address */ + +asm(" rte"); + +extern void _catchException (); + +/* This function is called when an exception occurs. It translates the + * return address found on the stack into an exception vector # which + * is then handled by either handle_exception or a system handler. + * _catchException provides a front end for both. + * + * stack on entry: stack on exit: + * Program counter MSWord exception # MSWord + * Program counter LSWord exception # MSWord + * Status Register + * Return Address MSWord + * Return Address LSWord + */ + +asm(" +.text +.align 2 +.globl _catchException +_catchException: +"); +DISABLE_INTERRUPTS(); +asm(" + moveml %d0-%d7/%a0-%a6,registers /* save registers */ + movel lastFrame,%a0 /* last frame pointer */ + + move.b #64,(0x00600001) + move.b (0x00600007),%d0 + andib #-64,%d0 + move.b %d0,(0x00600007) + +"); +SAVE_FP_REGS(); +asm(" + lea registers,%a5 /* get address of registers */ + movel %sp@+,%d2 /* pop return address */ + addq.l #6,%d2 + sub.l #0x200000,%d2 + divs #6,%d2 +/* addl #1530,%d2 */ /* convert return addr to */ +/* divs #6,%d2 */ /* exception number */ + extl %d2 + + moveql #3,%d3 /* assume a three word frame */ + + cmpiw #3,%d2 /* bus error or address error ? */ + bgt normal /* if >3 then normal error */ + movel %sp@+,%a0@- /* copy error info to frame buff*/ + movel %sp@+,%a0@- /* these are never used */ + moveql #7,%d3 /* this is a 7 word frame */ + +normal: + movew %sp@+,%d1 /* pop status register */ + movel %sp@+,%a4 /* pop program counter */ + movew %d1,%a5@(66) /* save sr */ + movel %a4,%a5@(68) /* save pc in _regisers[] */ + movel %a4,%a0@- /* copy pc to frame buffer */ + movew %d1,%a0@- /* copy sr to frame buffer */ + + movel %sp,superStack /* save supervisor sp */ + + andiw #0x2000,%d1 /* were we in supervisor mode ? */ + beq userMode + movel %a7,%a5@(60) /* save a7 */ + bra saveDone +userMode: + movel %usp,%a1 /* save user stack pointer */ + movel %a1,%a5@(60) /* save user stack pointer */ +saveDone: + + movew %d3,%a0@- /* push frame size in words */ + movel %d2,%a0@- /* push vector number */ + movel %a4,%a0@- /* push exception pc */ + +# +# save old frame link and set the new value + movel lastFrame,%a1 /* last frame pointer */ + movel %a1,%a0@- /* save pointer to prev frame */ + movel %a0,lastFrame + + movel %d2,%sp@- /* push exception num */ + movel exceptionHook,%a0 /* get address of handler */ + jbsr %a0@ /* and call it */ + clrl %sp@ /* replace exception num parm with frame ptr*/ + jbsr _returnFromException /* jbsr, but never returns */ +"); + + +/* + * remcomHandler is a front end for handle_exception. It moves the + * stack pointer into an area reserved for debugger use in case the + * breakpoint happened in supervisor mode. + */ +asm("remcomHandler:"); +asm(" addl #4,%sp"); /* pop off return address */ +asm(" movel %sp@+,%d0"); /* get the exception number */ +asm(" movel stackPtr,%sp"); /* move to remcom stack area */ +asm(" movel %d0,%sp@-"); /* push exception onto stack */ +asm(" andiw #0xf8ff,%sr"); +asm(" jbsr handle_exception"); /* this never returns */ +asm(" rts"); /* return */ + +void _returnFromException( Frame *frame ) +{ + /* if no passed in frame, use the last one */ + if (! frame) + { + frame = lastFrame; + frame->frameSize = 4; + frame->format = 0; + frame->fsaveHeader = -1; /* restore regs, but we dont have fsave info*/ + } + + + /* a 68000 cannot use the internal info pushed onto a bus error + * or address error frame when doing an RTE so don't put this info + * onto the stack or the stack will creep every time this happens. + */ + frame->frameSize=3; + + + /* throw away any frames in the list after this frame */ + lastFrame = frame; + + frame->sr = registers[(int) PS]; + frame->pc = registers[(int) PC]; + + if (registers[(int) PS] & 0x2000) + { + /* return to supervisor mode... */ + return_to_super(); + } + else + { /* return to user mode */ + return_to_user(); + } +} + +int hex(ch) +char ch; +{ + if ((ch >= 'a') && (ch <= 'f')) return (ch-'a'+10); + if ((ch >= '0') && (ch <= '9')) return (ch-'0'); + if ((ch >= 'A') && (ch <= 'F')) return (ch-'A'+10); + return (-1); +} + + +/* scan for the sequence $# */ +void getpacket(buffer) +char * buffer; +{ + unsigned char checksum; + unsigned char xmitcsum; + int i; + int count; + char ch; + + do { + /* wait around for the start character, ignore all other characters */ + while ((ch = getDebugChar()) != '$'); + checksum = 0; + xmitcsum = -1; + + count = 0; + + /* now, read until a # or end of buffer is found */ + while (count < BUFMAX) { + ch = getDebugChar(); + if (ch == '#') break; + checksum = checksum + ch; + buffer[count] = ch; + count = count + 1; + } + buffer[count] = 0; + + if (ch == '#') { + xmitcsum = hex(getDebugChar()) << 4; + xmitcsum += hex(getDebugChar()); + + if (checksum != xmitcsum) putDebugChar('-'); /* failed checksum */ + else { + putDebugChar('+'); /* successful transfer */ + /* if a sequence char is present, reply the sequence ID */ + if (buffer[2] == ':') { + putDebugChar( buffer[0] ); + putDebugChar( buffer[1] ); + /* remove sequence chars from buffer */ + count = db_strlen(buffer); + for (i=3; i <= count; i++) buffer[i-3] = buffer[i]; + } + } + } + } while (checksum != xmitcsum); + +} + +/* send the packet in buffer. The host get's one chance to read it. + This routine does not wait for a positive acknowledge. */ + + +void putpacket(buffer) +char * buffer; +{ + unsigned char checksum; + int count; + char ch; + + /* $#. */ + do { + putDebugChar('$'); + checksum = 0; + count = 0; + + while ((ch=buffer[count])) { + if (! putDebugChar(ch)) return; + checksum += ch; + count += 1; + } + + putDebugChar('#'); + putDebugChar(hexchars[checksum >> 4]); + putDebugChar(hexchars[checksum % 16]); + + } while (1 == 0); /* (getDebugChar() != '+'); */ + +} + +char remcomInBuffer[BUFMAX]; +char remcomOutBuffer[BUFMAX]; +static short error; + + +void debug_error(format, parm) +char * format; +char * parm; +{ + return; +} + +/* convert the memory pointed to by mem into hex, placing result in buf */ +/* return a pointer to the last char put in buf (null) */ +char* mem2hex(mem, buf, count) +char* mem; +char* buf; +int count; +{ + int i; + unsigned char ch; + for (i=0;i> 4]; + *buf++ = hexchars[ch % 16]; + } + *buf = 0; + return(buf); +} + +/* convert the hex array pointed to by buf into binary to be placed in mem */ +/* return a pointer to the character AFTER the last byte written */ +char* hex2mem(buf, mem, count) +char* buf; +char* mem; +int count; +{ + int i; + unsigned char ch; + for (i=0;i=0) + { + *intValue = (*intValue <<4) | hexValue; + numChars ++; + } + else + break; + + (*ptr)++; + } + + return (numChars); +} + +/* + * This function does all command procesing for interfacing to gdb. + */ +void handle_exception(int exceptionVector) +{ + int sigval; + int addr, length; + char * ptr; + int newPC; + Frame *frame; + + /* reply to host that an exception has occurred */ + sigval = computeSignal( exceptionVector ); + remcomOutBuffer[0] = 'S'; + remcomOutBuffer[1] = hexchars[sigval >> 4]; + remcomOutBuffer[2] = hexchars[sigval % 16]; + remcomOutBuffer[3] = 0; + + putpacket(remcomOutBuffer); + + while (1==1) { + error = 0; + remcomOutBuffer[0] = 0; + getpacket(remcomInBuffer); + switch (remcomInBuffer[0]) { + case '?' : remcomOutBuffer[0] = 'S'; + remcomOutBuffer[1] = hexchars[sigval >> 4]; + remcomOutBuffer[2] = hexchars[sigval % 16]; + remcomOutBuffer[3] = 0; + break; + case 'd' : remote_debug = !(remote_debug); /* toggle debug flag */ + break; + case 'g' : /* return the value of the CPU registers */ + mem2hex((char*) registers, remcomOutBuffer, NUMREGBYTES); + break; + case 'G' : /* set the value of the CPU registers - return OK */ + hex2mem(&remcomInBuffer[1], (char*) registers, NUMREGBYTES); + db_strcpy(remcomOutBuffer,"OK"); + break; + + /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */ + case 'm' : + /* TRY TO READ %x,%x. IF SUCCEED, SET PTR = 0 */ + ptr = &remcomInBuffer[1]; + if (hexToInt(&ptr,&addr)) + if (*(ptr++) == ',') + if (hexToInt(&ptr,&length)) + { + ptr = 0; + mem2hex((char*) addr, remcomOutBuffer, length); + } + + if (ptr) + { + db_strcpy(remcomOutBuffer,"E01"); + debug_error("malformed read memory command: %s",remcomInBuffer); + } + break; + + /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */ + case 'M' : + /* TRY TO READ '%x,%x:'. IF SUCCEED, SET PTR = 0 */ + ptr = &remcomInBuffer[1]; + if (hexToInt(&ptr,&addr)) + if (*(ptr++) == ',') + if (hexToInt(&ptr,&length)) + if (*(ptr++) == ':') + { + hex2mem(ptr, (char*) addr, length); + ptr = 0; + db_strcpy(remcomOutBuffer,"OK"); + } + if (ptr) + { + db_strcpy(remcomOutBuffer,"E02"); + debug_error("malformed write memory command: %s",remcomInBuffer); + } + break; + + /* cAA..AA Continue at address AA..AA(optional) */ + /* sAA..AA Step one instruction from AA..AA(optional) */ + case 'c' : + case 's' : + /* try to read optional parameter, pc unchanged if no parm */ + ptr = &remcomInBuffer[1]; + if (hexToInt(&ptr,&addr)) + registers[ PC ] = addr; + + newPC = registers[ PC]; + + /* clear the trace bit */ + registers[ PS ] &= 0x7fff; + + /* set the trace bit if we're stepping */ + if (remcomInBuffer[0] == 's') registers[ PS ] |= 0x8000; + + /* + * look for newPC in the linked list of exception frames. + * if it is found, use the old frame it. otherwise, + * fake up a dummy frame in returnFromException(). + */ + frame = lastFrame; + while (frame) + { + if (frame->exceptionPC == newPC) break; /* bingo! a match */ + /* + * for a breakpoint instruction, the saved pc may + * be off by two due to re-executing the instruction + * replaced by the trap instruction. Check for this. + */ + if ((frame->exceptionVector == 33) && + (frame->exceptionPC == (newPC+2))) break; + if (frame == frame->previous) + { + frame = 0; /* no match found */ + break; + } + frame = frame->previous; + } + + /* + * If we found a match for the PC AND we are not returning + * as a result of a breakpoint (33), + * trace exception (9), nmi (31), jmp to + * the old exception handler as if this code never ran. + */ + if (frame) + { + if ((frame->exceptionVector != 9) && + (frame->exceptionVector != 31) && + (frame->exceptionVector != 33)) + { + /* + * invoke the previous handler. + */ + if (oldExceptionHook) + (*oldExceptionHook) (frame->exceptionVector); + newPC = registers[ PC ]; /* pc may have changed */ + if (newPC != frame->exceptionPC) + { + /* re-use the last frame, we're skipping it (longjump?)*/ + frame = (Frame *) 0; + _returnFromException( frame ); /* this is a jump */ + } + } + } + + /* if we couldn't find a frame, create one */ + if (frame == 0) + { + frame = lastFrame -1 ; + + /* by using a bunch of print commands with breakpoints, + it's possible for the frame stack to creep down. If it creeps + too far, give up and reset it to the top. Normal use should + not see this happen. + */ + if ((unsigned int) (frame-2) < (unsigned int) &gdbFrameStack) + { + initializeRemcomErrorFrame(); + frame = lastFrame; + } + frame->previous = lastFrame; + lastFrame = frame; + frame = 0; /* null so _return... will properly initialize it */ + } + + _returnFromException( frame ); /* this is a jump */ + + break; + + /* kill the program */ + case 'k' : /* do nothing */ + break; + } /* switch */ + + /* reply to the request */ + putpacket(remcomOutBuffer); + } +} + + +void +initializeRemcomErrorFrame() +{ + lastFrame = ((Frame *) &gdbFrameStack[FRAMESIZE-1]) - 1; + lastFrame->previous = lastFrame; +} + +/* this function is used to set up exception handlers for tracing and + breakpoints */ +void set_debug_traps() +{ + extern void _debug_level7(); + extern void remcomHandler(); + int exception; + + initializeRemcomErrorFrame(); + stackPtr = &remcomStack[STACKSIZE/sizeof(int) - 1]; + + for (exception = 2; exception <= 23; exception++) + set_vector(_catchException,exception,0); + + /* level 7 interrupt */ + set_vector(_debug_level7,31,0); + + /* breakpoint exception (trap #1) */ + set_vector(_catchException,33,0); + + /* This is a trap #8 instruction. Apparently it is someone's software + convention for some sort of SIGFPE condition. Whose? How many + people are being screwed by having this code the way it is? + Is there a clean solution? */ + set_vector(_catchException,40,0); + + /* 48 to 54 are floating point coprocessor errors */ + for (exception = 48; exception <= 54; exception++) + set_vector(_catchException,exception,0); + + if (oldExceptionHook != remcomHandler) + { + oldExceptionHook = exceptionHook; + exceptionHook = remcomHandler; + } + + initialized = 1; + +} + +/* This function will generate a breakpoint exception. It is used at the + beginning of a program to sync up with a debugger and can be used + otherwise as a quick means to stop program execution and "break" into + the debugger. */ + +void breakpoint() +{ + if (initialized) BREAKPOINT(); +} + diff --git a/c/src/lib/libbsp/m68k/efi68k/startup/setvec.c b/c/src/lib/libbsp/m68k/efi68k/startup/setvec.c new file mode 100644 index 0000000000..39eb7a1fa1 --- /dev/null +++ b/c/src/lib/libbsp/m68k/efi68k/startup/setvec.c @@ -0,0 +1,45 @@ +/* set_vector + * + * This routine installs an interrupt vector on the efi68k. + * + * INPUT: + * handler - interrupt handler entry point + * vector - vector number + * type - 0 indicates raw hardware connect + * 1 indicates RTEMS interrupt connect + * + * RETURNS: + * address of previous interrupt handler + * + * 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 + +m68k_isr_entry set_vector( /* returns old vector */ + rtems_isr_entry handler, /* isr routine */ + rtems_vector_number vector, /* vector number */ + int type /* RTEMS or RAW intr */ +) +{ + int *p; + m68k_isr_entry previous_isr; + + if ( type ) + rtems_interrupt_catch( handler, vector, (rtems_isr_entry *) &previous_isr ); + else { + p = (int *)(vector*6-12+2+(int)_VBR); + previous_isr = (m68k_isr_entry) *p; /* return old ISR */ + *p = (int) handler; /* install new ISR */ + } + return previous_isr; +} + diff --git a/c/src/lib/libbsp/m68k/efi68k/timer/timer.c b/c/src/lib/libbsp/m68k/efi68k/timer/timer.c new file mode 100644 index 0000000000..b53e31ec0d --- /dev/null +++ b/c/src/lib/libbsp/m68k/efi68k/timer/timer.c @@ -0,0 +1,141 @@ +/* Timer_init() + * + * This routine initializes a timer in efi68k's DP8570A TCP + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * NOTE: It is important that the timer start/stop overhead be + * determined when porting or modifying this code. + * + * 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 + +rtems_boolean Timer_driver_Find_average_overhead; + +extern rtems_isr Clock_isr(); + +void Timer_initialize( void ) +{ + /* stop counter */ + *MSR = 0; + *T0CR = 0; + + /* + * Make sure isr is installed + */ + + set_vector( Clock_isr, TCP_ISR_LEVEL+24, 1); + + /* clear timer ISR count */ + Timer_interrupts = 0; + + /* load count (count down timer) */ + *MSR = 0; + *T0_MSB = 0xff; + *T0_LSB = 0xff; + + /* clear old interrupts */ + *MSR = T0; + + /* enable timer 0 interrupt */ + *MSR = RS; + *ICR0 |= T0E; + + /* + TSS = 1 starts the timer (timer resets on start) + M1/0 = 0/1 rate generator + C2/1/0 = 0/0/0 external clock (8MHz) (1/8 usec resolution) + RD = 0 read data (latchs count) + CHG = 0 hold + */ + *MSR = 0; + *T0CR = (TSS | M0); +} + +/* + * The following controls the behavior of Read_timer(). + * + * FIND_AVG_OVERHEAD * instructs the routine to return the "raw" count. + * + * AVG_OVEREHAD is the overhead for starting and stopping the timer. It + * is usually deducted from the number returned. + * + * LEAST_VALID is the lowest number this routine should trust. Numbers + * below this are "noise" and zero is returned. + */ + +#define AVG_OVERHEAD 0 /* It typically takes X.X microseconds */ + /* (Y countdowns) to start/stop the timer. */ + /* This value is in microseconds. */ +#define LEAST_VALID 1 /* Don't trust a clicks value lower than this */ + +/* + * Return timer value in 1/2-microsecond units + */ +int Read_timer( void ) +{ + rtems_unsigned16 clicks; + rtems_unsigned32 total; + rtems_unsigned32 msb, lsb; + + + /* + * Read the timer and see how many clicks it has been since counter + * rolled over. + */ + + *MSR = 0; + *T0CR |= RD; + /* must read MSB first */ + msb = *T0_MSB; + lsb = *T0_LSB; + clicks = 0xffff - ((msb << 8) | lsb); + + /* + * Total is calculated by taking into account the number of timer overflow + * interrupts since the timer was initialized and clicks since the last + * interrupts. + */ + + total = (Timer_interrupts * 0x10000 + clicks + 4)/8; /* in micoseconds */ + /* ^^^ round to nearest int */ + + if ( Timer_driver_Find_average_overhead == 1 ) + return total; /* in XXX microsecond units */ + + if ( total < LEAST_VALID ) + return 0; /* below timer resolution */ + + return (total - AVG_OVERHEAD); +} + + +/* + * Empty function call used in loops to measure basic cost of looping + * in Timing Test Suite. + */ + +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; +} -- cgit v1.2.3