From a24d946fc0e2420a93cc80fe3965d617251df2ba Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Tue, 6 Aug 2002 13:57:03 +0000 Subject: 2002-08-06 Chris Ziomkowski * .cvsignore, Makefile.am, README, bsp_specs, configure.ac, times, clock/.cvsignore, clock/Makefile.am, clock/clockdrv.c, console/.cvsignore, console/Makefile.am, console/console.c, console/console.h, include/.cvsignore, include/Makefile.am, include/bsp.h, start/.cvsignore, start/Makefile.am, start/start.S, startup/.cvsignore, startup/bspclean.c, startup/bspstart.c, startup/linkcmds, startup/main.c, startup/setvec.c, timer/.cvsignore, timer/Makefile.am, timer/timer.c, timer/timerisr.c, wrapup/.cvsignore, wrapup/Makefile.am, ChangeLog: New files added as part of merge from OpenCores repository. --- c/src/lib/libbsp/or32/orp/.cvsignore | 13 + c/src/lib/libbsp/or32/orp/ChangeLog | 12 + c/src/lib/libbsp/or32/orp/Makefile.am | 16 + c/src/lib/libbsp/or32/orp/README | 69 +++ c/src/lib/libbsp/or32/orp/bsp_specs | 12 + c/src/lib/libbsp/or32/orp/clock/.cvsignore | 2 + c/src/lib/libbsp/or32/orp/clock/Makefile.am | 32 ++ c/src/lib/libbsp/or32/orp/clock/clockdrv.c | 226 ++++++++ c/src/lib/libbsp/or32/orp/configure.ac | 42 ++ c/src/lib/libbsp/or32/orp/console/.cvsignore | 2 + c/src/lib/libbsp/or32/orp/console/Makefile.am | 34 ++ c/src/lib/libbsp/or32/orp/console/console.c | 377 ++++++++++++ c/src/lib/libbsp/or32/orp/console/console.h | 70 +++ c/src/lib/libbsp/or32/orp/include/.cvsignore | 2 + c/src/lib/libbsp/or32/orp/include/Makefile.am | 22 + c/src/lib/libbsp/or32/orp/include/bsp.h | 107 ++++ c/src/lib/libbsp/or32/orp/start/.cvsignore | 2 + c/src/lib/libbsp/or32/orp/start/Makefile.am | 31 + c/src/lib/libbsp/or32/orp/start/start.S | 787 ++++++++++++++++++++++++++ c/src/lib/libbsp/or32/orp/startup/.cvsignore | 2 + c/src/lib/libbsp/or32/orp/startup/bspclean.c | 25 + c/src/lib/libbsp/or32/orp/startup/bspstart.c | 122 ++++ c/src/lib/libbsp/or32/orp/startup/linkcmds | 63 +++ c/src/lib/libbsp/or32/orp/startup/main.c | 37 ++ c/src/lib/libbsp/or32/orp/startup/setvec.c | 43 ++ c/src/lib/libbsp/or32/orp/timer/.cvsignore | 2 + c/src/lib/libbsp/or32/orp/timer/Makefile.am | 34 ++ c/src/lib/libbsp/or32/orp/timer/timer.c | 104 ++++ c/src/lib/libbsp/or32/orp/timer/timerisr.c | 36 ++ c/src/lib/libbsp/or32/orp/times | 194 +++++++ c/src/lib/libbsp/or32/orp/wrapup/.cvsignore | 2 + c/src/lib/libbsp/or32/orp/wrapup/Makefile.am | 27 + 32 files changed, 2549 insertions(+) create mode 100644 c/src/lib/libbsp/or32/orp/.cvsignore create mode 100644 c/src/lib/libbsp/or32/orp/ChangeLog create mode 100644 c/src/lib/libbsp/or32/orp/Makefile.am create mode 100644 c/src/lib/libbsp/or32/orp/README create mode 100644 c/src/lib/libbsp/or32/orp/bsp_specs create mode 100644 c/src/lib/libbsp/or32/orp/clock/.cvsignore create mode 100644 c/src/lib/libbsp/or32/orp/clock/Makefile.am create mode 100644 c/src/lib/libbsp/or32/orp/clock/clockdrv.c create mode 100644 c/src/lib/libbsp/or32/orp/configure.ac create mode 100644 c/src/lib/libbsp/or32/orp/console/.cvsignore create mode 100644 c/src/lib/libbsp/or32/orp/console/Makefile.am create mode 100644 c/src/lib/libbsp/or32/orp/console/console.c create mode 100644 c/src/lib/libbsp/or32/orp/console/console.h create mode 100644 c/src/lib/libbsp/or32/orp/include/.cvsignore create mode 100644 c/src/lib/libbsp/or32/orp/include/Makefile.am create mode 100644 c/src/lib/libbsp/or32/orp/include/bsp.h create mode 100644 c/src/lib/libbsp/or32/orp/start/.cvsignore create mode 100644 c/src/lib/libbsp/or32/orp/start/Makefile.am create mode 100644 c/src/lib/libbsp/or32/orp/start/start.S create mode 100644 c/src/lib/libbsp/or32/orp/startup/.cvsignore create mode 100644 c/src/lib/libbsp/or32/orp/startup/bspclean.c create mode 100644 c/src/lib/libbsp/or32/orp/startup/bspstart.c create mode 100644 c/src/lib/libbsp/or32/orp/startup/linkcmds create mode 100644 c/src/lib/libbsp/or32/orp/startup/main.c create mode 100644 c/src/lib/libbsp/or32/orp/startup/setvec.c create mode 100644 c/src/lib/libbsp/or32/orp/timer/.cvsignore create mode 100644 c/src/lib/libbsp/or32/orp/timer/Makefile.am create mode 100644 c/src/lib/libbsp/or32/orp/timer/timer.c create mode 100644 c/src/lib/libbsp/or32/orp/timer/timerisr.c create mode 100644 c/src/lib/libbsp/or32/orp/times create mode 100644 c/src/lib/libbsp/or32/orp/wrapup/.cvsignore create mode 100644 c/src/lib/libbsp/or32/orp/wrapup/Makefile.am (limited to 'c/src/lib/libbsp/or32') diff --git a/c/src/lib/libbsp/or32/orp/.cvsignore b/c/src/lib/libbsp/or32/orp/.cvsignore new file mode 100644 index 0000000000..525275c115 --- /dev/null +++ b/c/src/lib/libbsp/or32/orp/.cvsignore @@ -0,0 +1,13 @@ +Makefile +Makefile.in +aclocal.m4 +config.cache +config.guess +config.log +config.status +config.sub +configure +depcomp +install-sh +missing +mkinstalldirs diff --git a/c/src/lib/libbsp/or32/orp/ChangeLog b/c/src/lib/libbsp/or32/orp/ChangeLog new file mode 100644 index 0000000000..75f207c5a8 --- /dev/null +++ b/c/src/lib/libbsp/or32/orp/ChangeLog @@ -0,0 +1,12 @@ +2002-08-06 Chris Ziomkowski + + * .cvsignore, Makefile.am, README, bsp_specs, configure.ac, times, + clock/.cvsignore, clock/Makefile.am, clock/clockdrv.c, + console/.cvsignore, console/Makefile.am, console/console.c, + console/console.h, include/.cvsignore, include/Makefile.am, + include/bsp.h, start/.cvsignore, start/Makefile.am, start/start.S, + startup/.cvsignore, startup/bspclean.c, startup/bspstart.c, + startup/linkcmds, startup/main.c, startup/setvec.c, timer/.cvsignore, + timer/Makefile.am, timer/timer.c, timer/timerisr.c, + wrapup/.cvsignore, wrapup/Makefile.am, ChangeLog: New files added + as part of merge from OpenCores repository. diff --git a/c/src/lib/libbsp/or32/orp/Makefile.am b/c/src/lib/libbsp/or32/orp/Makefile.am new file mode 100644 index 0000000000..4a99649850 --- /dev/null +++ b/c/src/lib/libbsp/or32/orp/Makefile.am @@ -0,0 +1,16 @@ +## +## $Id$ +## + +ACLOCAL_AMFLAGS = -I ../../../../../../aclocal + +# wrapup is the one that actually builds and installs the library +# from the individual .rel files built in other directories +SUBDIRS = . include clock console startup timer start wrapup + +include $(top_srcdir)/../../bsp.am + +EXTRA_DIST = bsp_specs + +include $(top_srcdir)/../../../../../../automake/subdirs.am +include $(top_srcdir)/../../../../../../automake/local.am diff --git a/c/src/lib/libbsp/or32/orp/README b/c/src/lib/libbsp/or32/orp/README new file mode 100644 index 0000000000..8ed80e29f8 --- /dev/null +++ b/c/src/lib/libbsp/or32/orp/README @@ -0,0 +1,69 @@ +# +# $Id$ +# +# This is a sample hardware description file for a BSP. This comment +# block does not have to appear in a real one. The intention of this +# file is to provide a central place to look when searching for +# information about a board when starting a new BSP. For example, +# you may want to find an existing timer driver for the chip you are +# using on your board. It is easier to grep for the chip name in +# all of the HARDWARE files than to peruse the source tree. Hopefully, +# making the HARDDWARE files accurate will also alleviate the common +# problem of not knowing anything about a board based on its BSP +# name. +# +# NOTE: If you have a class of peripheral chip on board which +# is not in this list please add it to this file so +# others will also use the same name. +# +# Timer resolution is the way it is configured in this BSP. +# On a counting timer, this is the length of time which +# corresponds to 1 count. +# + +BSP NAME: fastsbc1 +BOARD: Fasssst Computers, Fast SBC-1 +BUS: SchoolBus +CPU FAMILY: i386 +CPU: Intel Hexium +COPROCESSORS: Witch Hex87 +MODE: 32 bit mode + +DEBUG MONITOR: HexBug + +PERIPHERALS +=========== +TIMERS: Intel i8254 + RESOLUTION: .0001 microseconds +SERIAL PORTS: Zilog Z8530 (with 2 ports) +REAL-TIME CLOCK: RTC-4 +DMA: Intel i8259 +VIDEO: none +SCSI: none +NETWORKING: none + +DRIVER INFORMATION +================== +CLOCK DRIVER: RTC-4 +IOSUPP DRIVER: Zilog Z8530 port A +SHMSUPP: polled and interrupts +TIMER DRIVER: Intel i8254 +TTY DRIVER: stub only + +STDIO +===== +PORT: Console port 0 +ELECTRICAL: RS-232 +BAUD: 9600 +BITS PER CHARACTER: 8 +PARITY: None +STOP BITS: 1 + +NOTES +===== + +(1) 900 Mhz and 950 Mhz versions. + +(2) 1 Gb or 2 Gb RAM. + +(3) PC compatible if HexBug not enabled. diff --git a/c/src/lib/libbsp/or32/orp/bsp_specs b/c/src/lib/libbsp/or32/orp/bsp_specs new file mode 100644 index 0000000000..1a49230640 --- /dev/null +++ b/c/src/lib/libbsp/or32/orp/bsp_specs @@ -0,0 +1,12 @@ +%rename cpp old_cpp +%rename lib old_lib + +*cpp: +%(old_cpp) %{qrtems: -D__embedded__} -Asystem(embedded) + +*lib: +%{!qrtems: %(old_lib)} \ +%{qrtems: --start-group %{!qrtems_debug: -lrtemsall } %{qrtems_debug: -lrtemsall_g} \ + -lc -lgcc --end-group \ + %{!qnolinkcmds: -T linkcmds%s}} + diff --git a/c/src/lib/libbsp/or32/orp/clock/.cvsignore b/c/src/lib/libbsp/or32/orp/clock/.cvsignore new file mode 100644 index 0000000000..282522db03 --- /dev/null +++ b/c/src/lib/libbsp/or32/orp/clock/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/c/src/lib/libbsp/or32/orp/clock/Makefile.am b/c/src/lib/libbsp/or32/orp/clock/Makefile.am new file mode 100644 index 0000000000..3975bba608 --- /dev/null +++ b/c/src/lib/libbsp/or32/orp/clock/Makefile.am @@ -0,0 +1,32 @@ +## +## $Id$ +## + + +PGM = $(ARCH)/clock.rel + +C_FILES = clockdrv.c +C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o) + +OBJS = $(C_O_FILES) + +include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg +include $(top_srcdir)/../../../../../../automake/compile.am +include $(top_srcdir)/../../../../../../automake/lib.am + +# +# (OPTIONAL) Add local stuff here using += +# + +$(PGM): $(OBJS) + $(make-rel) + +# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile + +all-local: $(ARCH) $(OBJS) $(PGM) + +.PRECIOUS: $(PGM) + +EXTRA_DIST = clockdrv.c + +include $(top_srcdir)/../../../../../../automake/local.am diff --git a/c/src/lib/libbsp/or32/orp/clock/clockdrv.c b/c/src/lib/libbsp/or32/orp/clock/clockdrv.c new file mode 100644 index 0000000000..60aa481e1a --- /dev/null +++ b/c/src/lib/libbsp/or32/orp/clock/clockdrv.c @@ -0,0 +1,226 @@ +/* ckinit.c + * + * This file provides a template for the clock device driver initialization. + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include + +#include +#include +#include +static void (*old_handler)(unsigned int,unsigned int,unsigned int,unsigned int); + +void Clock_exit( void ); +void Clock_isr( rtems_vector_number vector,unsigned int pc, + unsigned int address, unsigned int sr); + + +/* + * The interrupt vector number associated with the clock tick device + * driver. + */ + +#define CLOCK_VECTOR 8 + +/* + * Clock_driver_ticks is a monotonically increasing counter of the + * number of clock ticks since the driver was initialized. + */ + +volatile rtems_unsigned32 Clock_driver_ticks; + +/* + * Clock_isrs is the number of clock ISRs until the next invocation of + * the RTEMS clock tick routine. The clock tick device driver + * gets an interrupt once a millisecond and counts down until the + * length of time between the user configured microseconds per tick + * has passed. + */ + +rtems_unsigned32 Clock_isrs; /* ISRs until next tick */ + +/* + * 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 Clock_exit( void ); + +/* Write this to restart the Timer. Sets mode = 01, + interrupts enabled, interrupt not pending, report + at 200,000 (1 msec on 200 MHz CPU) */ +static const unsigned int TTMR_RESET = 0x60030D40; + +/* + * Isr Handler + */ + +void Clock_isr(unsigned32 vector, + unsigned32 pc, + unsigned32 ear, + unsigned32 sr) +{ + register int pending; + register int value = 0x60002710; + + /* Was it us? */ + asm volatile ("l.mfspr %0,r0,0x4802 \n\t" /* Read the PIC status */ + "l.andi %0,%0,0x8 \n\t" : "=r" (pending)); + + if(pending) + { + rtems_clock_tick(); + asm ("l.mtspr r0,%0,0x5000 \n\t" :: "r" (value)); + } + + if(old_handler) + (*old_handler)(vector,pc,ear,sr); +} + +/* + * Install_clock + * + * Install a clock tick handler and reprograms the chip. This + * is used to initially establish the clock tick. + */ + +void Install_clock() +{ + unsigned32 tmp,sr,ttmr,ttcr; + extern unsigned32 Or1k_Interrupt_Vectors[16]; + + ttmr = TTMR_RESET; /* Reset value */ + ttcr = 0; /* Start at 0 */ + + /* + * Initialize the clock tick device driver variables + */ + + /* Make sure the Timer (interrupt 3) is enabled and + reports a high prority interrupt */ + + asm volatile ("l.mfspr %0,r0,0x4800 \n\t" /* Get the PIC mask */ + "l.ori %0,%0,0x8 \n\t" /* Enable int 3 */ + "l.mtspr r0,%0,0x4800 \n\t" /* Write back mask */ + "l.mfspr %0,r0,0x4801 \n\t" /* Get priority mask */ + "l.ori %0,%0,0x8 \n\t" /* Set us to high */ + "l.mtspr r0,%0,0x4801 \n\t" /* Write back to PICPR */ + : "=r" (tmp)); + + /* Generate a 1 kHz interrupt */ + asm volatile ("l.mfspr %0,r0,0x11 \n\t" /* Get the current setting */ + "l.addi %1,r0,-5 \n\t" + "l.and %1,%1,%0 \n\t" /* Turn off interrupts */ + "l.mtspr r0,%1,0x11 \n\t" /* Set it in SR */ + "l.mtspr r0,%2,0x5000\n\t" /* Set TTMR */ + "l.mtspr r0,%3,0x5100\n\t" /* Set TTCR */ + : "=&r" (sr), "=&r" (tmp) : "r" (ttmr), "r" (ttcr)); + + old_handler = (void(*)(unsigned int,unsigned int,unsigned int,unsigned int)) + Or1k_Interrupt_Vectors[8]; + Or1k_Interrupt_Vectors[8] = (unsigned32)Clock_isr; + + asm volatile ("l.mtspr r0,%0,0x11\n\t":: "r" (sr)); + + Clock_driver_ticks = 0; + + /* + * Schedule the clock cleanup routine to execute if the application exits. + */ + + atexit( Clock_exit ); +} + +/* + * Clean up before the application exits + */ + +void Clock_exit( void ) +{ + register int temp1; + register int temp2; + + /* In the case of a fatal error, we should shut down + all the interrupts so we don't get woken up again. */ + /* First, turn off the clock in the PIC */ + + asm volatile ("l.mfspr %0,r0,0x4800 \n\t" /* Get the PIC mask */ + "l.addi %1,%1,-9 \n\t" /* Create a mask to disable */ + "l.and %0,%1,%0 \n\t" /* Mask us out */ + "l.mtspr r0,%0,0x4800 \n\t" /* Write back mask */ + "l.mfspr %0,r0,0x4801 \n\t" /* Get priority mask */ + "l.and %0,%1,%0 \n\t" /* Set us to low */ + "l.mtspr r0,%0,0x4801 \n\t" /* Write back to PICPR */ + : "=r" (temp1), "=r" (temp2)); + + /* Now turn off the clock at the timer */ + asm volatile ("l.mtspr r0,r0,0x5000\n\t" /* Clear TTMR */ + "l.mtspr r0,r0,0x5100\n\t"); /* Clear TTCR */ +} + +/* + * Clock_initialize + * + * Device driver entry point for clock tick driver initialization. + */ + +rtems_device_driver Clock_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *pargp +) +{ + Install_clock(); + + /* + * 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_unsigned32 isrlevel; + 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,0,0,0); + } + else if (args->command == rtems_build_name('N', 'E', 'W', ' ')) + { + rtems_interrupt_disable( isrlevel ); + (void) set_vector( args->buffer, CLOCK_VECTOR, 1 ); + rtems_interrupt_enable( isrlevel ); + } + +done: + return RTEMS_SUCCESSFUL; +} diff --git a/c/src/lib/libbsp/or32/orp/configure.ac b/c/src/lib/libbsp/or32/orp/configure.ac new file mode 100644 index 0000000000..f5808aa9f4 --- /dev/null +++ b/c/src/lib/libbsp/or32/orp/configure.ac @@ -0,0 +1,42 @@ +## Process this file with autoconf to produce a configure script. +## +## $Id$ + +AC_PREREQ(2.52) +AC_INIT([rtems-c-src-lib-libbsp-arm-armulator],[_RTEMS_VERSION],[rtems-bugs@OARcorp.com]) +AC_CONFIG_SRCDIR([bsp_specs]) +RTEMS_TOP(../../../../../..) +AC_CONFIG_AUX_DIR(../../../../../..) + +RTEMS_CANONICAL_TARGET_CPU +AM_INIT_AUTOMAKE([no-define foreign 1.6]) +RTEMS_BSP_CONFIGURE + +RTEMS_PROG_CC_FOR_TARGET([-ansi -fasm]) +RTEMS_CANONICALIZE_TOOLS + +# From newlib +# Select which debug protocol is being used. +# ARM_RDP_MONITOR selects the Demon monitor. +# ARM_RDI_MONITOR selects the Angel monitor. +# If neither are defined, then hard coded defaults will be used +# to create the program's environment. + +RTEMS_BSPOPTS_SET([ARM_RDI_MONITOR],[*],[1]) +RTEMS_BSPOPTS_HELP([ARM_RDI_MONITOR], +[If defined enable Angel monitor support]) + +RTEMS_BSPOPTS_SET([ARM_RDP_MONITOR],[*],[]) +RTEMS_BSPOPTS_HELP([ARM_RDP_MONITOR], +[If defined enable Demon monitor support]) + +# Explicitly list all Makefiles here +AC_CONFIG_FILES([Makefile +clock/Makefile +console/Makefile +include/Makefile +start/Makefile +startup/Makefile +timer/Makefile +wrapup/Makefile]) +AC_OUTPUT diff --git a/c/src/lib/libbsp/or32/orp/console/.cvsignore b/c/src/lib/libbsp/or32/orp/console/.cvsignore new file mode 100644 index 0000000000..282522db03 --- /dev/null +++ b/c/src/lib/libbsp/or32/orp/console/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/c/src/lib/libbsp/or32/orp/console/Makefile.am b/c/src/lib/libbsp/or32/orp/console/Makefile.am new file mode 100644 index 0000000000..18e8af2301 --- /dev/null +++ b/c/src/lib/libbsp/or32/orp/console/Makefile.am @@ -0,0 +1,34 @@ +## +## $Id$ +## + + +VPATH = @srcdir@:@srcdir@/../../../shared + +PGM = $(ARCH)/console.rel + +C_FILES = console.c +C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o) + +OBJS = $(C_O_FILES) + +include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg +include $(top_srcdir)/../../../../../../automake/compile.am +include $(top_srcdir)/../../../../../../automake/lib.am + +# +# (OPTIONAL) Add local stuff here using += +# + +$(PGM): $(OBJS) + $(make-rel) + +# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile + +all-local: $(ARCH) $(OBJS) $(PGM) + +.PRECIOUS: $(PGM) + +EXTRA_DIST = console.c console.h + +include $(top_srcdir)/../../../../../../automake/local.am diff --git a/c/src/lib/libbsp/or32/orp/console/console.c b/c/src/lib/libbsp/or32/orp/console/console.c new file mode 100644 index 0000000000..a5081c1b50 --- /dev/null +++ b/c/src/lib/libbsp/or32/orp/console/console.c @@ -0,0 +1,377 @@ +/* + * This file contains the template for a console IO package. + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * This file adapted from no_bsp board library of the RTEMS distribution. + * The body has been modified for the Bender Or1k implementation by + * Chris Ziomkowski. + */ + +#define BENDER_INIT + +#include +#include +#include "console.h" + +static int localEcho; +static UART_16450* uart = (UART_16450*)0x80000000; /* This is where the simulator puts it */ + +/* console_initialize + * + * This routine initializes the console IO driver. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * Return values: + */ + +void (*old_handler)(unsigned int,unsigned int,unsigned int,unsigned int); + +void console_interrupt(unsigned int vector,unsigned int pc, + unsigned int effective_addr, unsigned int status) +{ + int reason; + register int pending; + + /* First thing's first...is this for us? */ + asm volatile ("l.mfspr %0,r0,0x4802 \n\t" /* Read the PIC status */ + "l.andi %0,%0,0x4 \n\t" : "=r" (pending)); + + if(pending) + { + reason = uart->read.IIR; + + switch(reason) + { + case 0: /* Interrupt because of modem status */ + break; + case 2: /* Interrupt because Transmitter empty */ + break; + case 4: /* Interrupt because Received data available */ + break; + case 6: /* Interrupt because Status Register */ + break; + case 12: /* Interrupt because of character timeout (16550 only) */ + break; + default: /* No interrupt */ + break; + } + } + + if(old_handler) + (*old_handler)(vector,pc,effective_addr,status); +} + +rtems_device_driver console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + rtems_status_code status; + int tmp,tmp2; + unsigned32 sr; + extern unsigned32 Or1k_Interrupt_Vectors[16]; + + /* Make sure the UART (interrupt 2) is enabled and + reports a low prority interrupt */ + asm volatile ("l.mfspr %0,r0,0x4800 \n\t" /* Get the PIC mask */ + "l.ori %0,%0,0x4 \n\t" /* Enable int 2 */ + "l.mtspr r0,%0,0x4800 \n\t" /* Write back mask */ + "l.mfspr %0,r0,0x4801 \n\t" /* Get priority mask */ + "l.addi %1,r0,-5 \n\t" + "l.and %0,%0,%1 \n\t" /* Set us to low */ + "l.mtspr r0,%0,0x4801 \n\t" /* Write back to PICPR */ + : "=r" (tmp), "=r" (tmp2)); + + /* Install the interrupt handler */ + asm volatile ("l.mfspr %0,r0,0x11 \n\t" + "l.addi %1,r0,-5 \n\t" + "l.and %1,%1,%0 \n\t" + "l.mtspr r0,%1,0x11 \n\t": "=&r" (sr) : "r" (tmp)); + + old_handler = (void(*)(unsigned int,unsigned int,unsigned int,unsigned int)) + Or1k_Interrupt_Vectors[5]; + Or1k_Interrupt_Vectors[5] = (unsigned32)console_interrupt; + + asm volatile ("l.mtspr r0,%0,0x11\n\t":: "r" (sr)); + + /* Assume 1843.2/16 kHz clock */ + uart->latch.LCR = 0x80; /* Set the divisor latch bit */ + uart->latch.DLM = 2; /* 57,600 */ + uart->latch.DLL = 0; + uart->write.LCR = 0x03; /* 8-N-1 */ + uart->write.MCR = 0x03; /* Assert RTS & DTR */ + /* uart->write.FCR = 0x00; */ /* Make sure we're in 16450 mode... Ignore for 16450 driver */ + uart->write.IER = 0x05; /* Don't worry about TEMT unless we need to. */ + + tmp = uart->read.LSR; /* Make sure interrupts are cleared */ + tmp = uart->read.RBR; /* Clear the input buffer */ + tmp = uart->read.MSR; /* Clear the modem status register */ + + localEcho = 1; /* Turn on local echo */ + + 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 +) +{ + *ch = '\0'; /* return NULL for no particular reason */ + return(TRUE); +} + +/* inbyte + * + * This routine reads a character from the SOURCE. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * Return values: + * character read from SOURCE + */ + +char inbyte( void ) +{ + unsigned int stat; + + stat = uart->read.LSR; + while(!(stat & 0x01)) /* ! Data Ready */ + { + rtems_task_wake_after( RTEMS_YIELD_PROCESSOR ); + stat = uart->read.LSR; + } + + return uart->read.RBR; /* Return the character */ +} + +/* outbyte + * + * This routine transmits a character out the SOURCE. Flow + * control is not currently enabled. + * + * Input parameters: + * ch - character to be transmitted + * + * Output parameters: NONE + */ + +void outbyte(char ch) +{ + unsigned int stat; + /* + * Carriage Return/New line translation. + */ + + stat = uart->read.LSR; + while(!(stat & 0x40)) /* ! TEMT */ + { + rtems_task_wake_after( RTEMS_YIELD_PROCESSOR ); + stat = uart->read.LSR; + } + + uart->write.THR = ch; + if ( ch == '\n' ) + outbyte( '\r' ); +} + + +/* + * 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'; + if(localEcho) + outbyte('\n' ); /* newline */ + break; /* Return for a newline */ + } + else if (buffer[ count ] == '\b' && count > 0 ) + { + if(localEcho) + { + outbyte('\b' ); /* move back one space */ + outbyte(' ' ); /* erase the character */ + outbyte('\b' ); /* move back one space */ + } + count-=2; + } + else if(localEcho) + outbyte(buffer[ count ]); /* echo the character */ + } + + 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 +) +{ + int param,div; + ConsoleIOCTLRequest* request = (ConsoleIOCTLRequest*)arg; + + if (!arg) + return RTEMS_INVALID_ADDRESS; + + switch(request->command) + { + case TERM_LOCAL_ECHO: + param = (int)(request->data); + if(param < 0 || param > 1) + return RTEMS_INVALID_NUMBER; + localEcho = param; + break; + case TERM_BIT_RATE: + param = (int)(request->data); + switch(param) + { + case 50: + case 150: + case 300: + case 600: + case 1200: + case 1800: + case 2000: + case 2400: + case 3600: + case 4800: + case 7200: + case 9600: + case 19200: + case 38400: + case 57600: + case 115200: + div = 115200/param; + uart->latch.LCR |= 0x80; /* Set the divisor latch bit */ + uart->latch.DLM = div & 0xFF; + uart->latch.DLL = div >> 8; + uart->write.LCR &= 0x7F; /* Clear the divisor latch bit */ + break; + default: + return RTEMS_INVALID_NUMBER; + } + break; + default: + return RTEMS_NOT_CONFIGURED; + } + + return RTEMS_SUCCESSFUL; +} diff --git a/c/src/lib/libbsp/or32/orp/console/console.h b/c/src/lib/libbsp/or32/orp/console/console.h new file mode 100644 index 0000000000..91ebfa2d69 --- /dev/null +++ b/c/src/lib/libbsp/or32/orp/console/console.h @@ -0,0 +1,70 @@ +/* console.h -- console header file for the Bender board using the + * Or1k architecture. + * + * Copyright (C) 2001 Chris Ziomkowski, chris@asics.ws + * + * This file is distributed as part of the RTEMS package from + * OAR Corporation, and follows the licensing and distribution + * terms as stated for RTEMS. + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + */ + +#ifndef _CONSOLE_H +#define _CONSOLE_H + +typedef enum { + TERM_LOCAL_ECHO, + TERM_BIT_RATE, +} ConsoleIOCTLCommand; + +typedef struct { + ConsoleIOCTLCommand command; + void* data; +} ConsoleIOCTLRequest; + +typedef struct { + unsigned char RBR; + unsigned char IER; + unsigned char IIR; + unsigned char LCR; + unsigned char MCR; + unsigned char LSR; + unsigned char MSR; + unsigned char SCR; +} UART_16450_Read; + +typedef struct { + unsigned char THR; + unsigned char IER; + unsigned char IIR; + unsigned char LCR; + unsigned char MCR; + unsigned char LSR; + unsigned char MSR; + unsigned char SCR; +} UART_16450_Write; + +typedef struct { + unsigned char DLM; + unsigned char DLL; + unsigned char IIR; + unsigned char LCR; + unsigned char MCR; + unsigned char LSR; + unsigned char MSR; + unsigned char SCR; +} UART_16450_Latch; + +typedef union { + UART_16450_Read read; + UART_16450_Write write; + UART_16450_Latch latch; +} UART_16450; + +#endif diff --git a/c/src/lib/libbsp/or32/orp/include/.cvsignore b/c/src/lib/libbsp/or32/orp/include/.cvsignore new file mode 100644 index 0000000000..282522db03 --- /dev/null +++ b/c/src/lib/libbsp/or32/orp/include/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/c/src/lib/libbsp/or32/orp/include/Makefile.am b/c/src/lib/libbsp/or32/orp/include/Makefile.am new file mode 100644 index 0000000000..be40c2aced --- /dev/null +++ b/c/src/lib/libbsp/or32/orp/include/Makefile.am @@ -0,0 +1,22 @@ +## +## $Id$ +## + + +include_HEADERS = bsp.h coverhd.h bspopts.h + +$(PROJECT_INCLUDE): + $(mkinstalldirs) $@ + +$(PROJECT_INCLUDE)/%.h: %.h + $(INSTALL_DATA) $< $@ + +coverhd.h: $(top_srcdir)/../../shared/include/coverhd.h + cp $< $@ +CLEANFILES = coverhd.h + +TMPINSTALL_FILES = $(PROJECT_INCLUDE) $(include_HEADERS:%=$(PROJECT_INCLUDE)/%) + +all-local: $(TMPINSTALL_FILES) + +include $(top_srcdir)/../../../../../../automake/local.am diff --git a/c/src/lib/libbsp/or32/orp/include/bsp.h b/c/src/lib/libbsp/or32/orp/include/bsp.h new file mode 100644 index 0000000000..3f8150e42e --- /dev/null +++ b/c/src/lib/libbsp/or32/orp/include/bsp.h @@ -0,0 +1,107 @@ +/* bsp.h + * + * This include file contains all board IO definitions. + * + * XXX : put yours in here + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#ifndef __NO_BSP_h +#define __NO_BSP_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/* + * confdefs.h overrides for this BSP: + * - number of termios serial ports (defaults to 1) + * - Interrupt stack space is not minimum if defined. + */ + +/* #define CONFIGURE_NUMBER_OF_TERMIOS_PORTS 2 */ +#define CONFIGURE_INTERRUPT_STACK_MEMORY (4 * 1024) + +/* + * 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 */ + +/* + * Stuff for Time Test 27 + */ + +#define MUST_WAIT_FOR_INTERRUPT 0 + +#define Install_tm27_vector( handler ) set_vector( (handler), 0, 1 ) + +#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 ) \ + { \ + } + +/* Constants */ + +#define RAM_START 0 +#define RAM_END 0x100000 + +/* miscellaneous stuff assumed to exist */ + +extern rtems_configuration_table BSP_Configuration; + +/* + * Device Driver Table Entries + */ + +/* + * NOTE: Use the standard Console driver entry + */ + +/* + * NOTE: Use the standard Clock driver entry + */ + +/* functions */ + +void bsp_cleanup( void ); + +no_cpu_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 */ +); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/c/src/lib/libbsp/or32/orp/start/.cvsignore b/c/src/lib/libbsp/or32/orp/start/.cvsignore new file mode 100644 index 0000000000..282522db03 --- /dev/null +++ b/c/src/lib/libbsp/or32/orp/start/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/c/src/lib/libbsp/or32/orp/start/Makefile.am b/c/src/lib/libbsp/or32/orp/start/Makefile.am new file mode 100644 index 0000000000..6a5f267d10 --- /dev/null +++ b/c/src/lib/libbsp/or32/orp/start/Makefile.am @@ -0,0 +1,31 @@ +## +## $Id$ +## + +S_FILES = start.S +S_O_FILES = $(S_FILES:%.c=$(ARCH)/%.o) + +OBJS = $(S_O_FILES) + +include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg +include $(top_srcdir)/../../../../../../automake/compile.am +include $(top_srcdir)/../../../../../../automake/lib.am + +# +# (OPTIONAL) Add local stuff here using += +# + +bsplib_DATA = $(PROJECT_RELEASE)/lib/start$(LIB_VARIANT).o + +$(PROJECT_RELEASE)/lib/start$(LIB_VARIANT).o: $(ARCH)/start.o + $(INSTALL_DATA) $< $@ + +TMPINSTALL_FILES += $(PROJECT_RELEASE)/lib/start$(LIB_VARIANT).o + +all-local: $(ARCH) $(OBJS) $(ARCH)/start.o $(TMPINSTALL_FILES) + +.PRECIOUS: $(ARCH)/start.o + +EXTRA_DIST = start.S + +include $(top_srcdir)/../../../../../../automake/local.am diff --git a/c/src/lib/libbsp/or32/orp/start/start.S b/c/src/lib/libbsp/or32/orp/start/start.S new file mode 100644 index 0000000000..45cd0d6769 --- /dev/null +++ b/c/src/lib/libbsp/or32/orp/start/start.S @@ -0,0 +1,787 @@ +/* start.S -- bootup code for the Bender board using the Or1k + * architecture. + * + * Copyright (C) 2001 Chris Ziomkowski, chris@asics.ws + * + * This file is distributed as part of the RTEMS package from + * OAR Corporation, and follows the licensing and distribution + * terms as stated for RTEMS. + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + */ + +#include "asm.h" + + +/* Since we don't yet have a memory map for Bender, I am + assuming the following. Hopefully, this will be easily + modified once we get the real values. + + 0x00000000 - 0x00200000: Flash/ROM (boot code / 2 MB) + 0x01000000 - 0x010FFFFF: Synchronous SRAM (area 2 / 1 MB) + 0x10000000 - 0x1FFFFFFF: External SDRAM (area 3 / 256 MB) + 0x20000000 - 0x2FFFFFFF: External SDRAM (area 4 / 256 MB) + + 0x80000000 - 0x8000001F: 4 16550 UART controllers + 0x80010000 - 0x80017FFF: Internal Bender RAM + 0x80020000 - 0xFFFFFFFF: Memory mapped Bender Peripherals + + For this version, I assume that only the flash and 32 MB + of RAM in area 3 are populated. Everything else should + return a bus error when accessed. +*/ +.file "start.S" + +.data + PUBLIC(Or1k_Interrupt_Vectors) +SYM (Or1k_Interrupt_Vectors): + .word 0x00000000 # No Vector + .word _start # Reset Vector (Ignored) + .word __Internal_error_Occurred # Bus Error + .word __Internal_error_Occurred # Data Page Fault + .word __Internal_error_Occurred # Instruction Page Fault + .word __int_reenable # Low Priority Interrupt + .word __Internal_error_Occurred # Alignment Exception + .word __Internal_error_Occurred # Illegal Instruction Exception + .word __int_reenable # High Priority Interrupt + .word __Internal_error_Occurred # ITBL Miss + .word __Internal_error_Occurred # DTBL Miss + .word 0x00000000 # Range Exception + .word 0x00000000 # System Call + .word 0x00000000 # Breakpoint + .word 0x00000000 # Trap + + PUBLIC(BOTTOM_OF_MEMORY) +SYM (BOTTOM_OF_MEMORY): + .word 0x00000000 # Assume RAM @ 0 for the sim + + PUBLIC(TOP_OF_MEMORY) +SYM (TOP_OF_MEMORY): + .word 0x800000 # Assume RAM @ 0 for the sim + + PUBLIC(_mem_end) +SYM (_mem_end): + .word 0x00000000 + + BEGIN_CODE + .org 0x0 + /**************/ + /* _panic */ + /**************/ + + /* Place the panic vector at 0 */ + +.proc __panic + .def __panic + .val __panic + .scl 2 + .type 044 + .endef + .global __panic +__panic: + + l.jal __exit + l.nop + +.endproc __panic + .def __panic + .val . + .scl -1 + .endef + + /* Exception processing...first, we will save the + 16 non callee saved registers which could be + corrupted by calling a C function. We have no + way of knowing which of these will be used, so + we have to save all of them. We will then save + the EPCR and ESR, in case a nested exception is + called. Next, we call the user function. We then + restore all the registers to their original + values, and finally disable exceptions, restore + EPCR and ESR (EEAR is not essential to restore) + and then return from the interrupt. */ + + /******************************************/ + /* Normal exception handling */ + /* Called with 80 bytes allocated on the */ + /* stack, the vector function in r11, and */ + /* the vector number in r3. Original */ + /* values at 28(r1) and 0(r1). */ + /******************************************/ +.proc ___standard_exception + .def ___standard_exception + .val ___standard_exception + .scl 2 + .type 044 + .endef + .global ___standard_exception +___standard_exception: + l.sfeqi r11,0 /* Ignore it if it is zero */ + l.bf L2_2 + l.sw 4(r1),r4 /* Save r4 */ + + /* Ignore fast context switching in this release. */ + /* It's poorly conceived, and will probably never */ + /* be implemented... */ + + l.sw 8(r1),r5 + l.sw 12(r1),r6 + l.sw 16(r1),r7 + + l.mfspr r4,r0,0x20 /* Save EPCR */ + l.mfspr r5,r0,0x30 /* Save EEAR */ + l.mfspr r6,r0,0x40 /* Save ESR */ + + l.mfspr r7,r0,17 + l.ori r7,r7,2 + l.mtspr r0,r7,17 /* Reenable exceptions */ + + l.sw 20(r1),r8 + l.sw 24(r1),r9 + l.sw 32(r1),r12 + l.sw 36(r1),r14 + l.sw 40(r1),r16 + l.sw 44(r1),r18 + l.sw 48(r1),r20 + l.sw 52(r1),r22 + l.sw 56(r1),r24 + l.sw 60(r1),r26 + l.sw 64(r1),r28 + l.sw 68(r1),r30 + l.sw 72(r1),r4 /* Save EPCR. User could change r4 */ + + /* Now, call the installed handler with the arguments: + r3 ==> vector # (1-14) + r4 ==> EPCR + r5 ==> EEAR + r6 ==> ESR + r11 ==> User function + */ + + l.jal ___user_function /* Call the user routine */ + l.sw 76(r1),r6 /* Save ESR. User could change r6 */ + /* Ignore r5 (EEAR). It is not critical for state */ + + l.lwz r30,68(r1) + l.lwz r28,64(r1) + l.lwz r26,60(r1) + l.lwz r24,56(r1) + l.lwz r22,52(r1) + l.lwz r20,48(r1) + l.lwz r18,44(r1) + l.lwz r16,40(r1) + l.lwz r14,36(r1) + l.lwz r12,32(r1) + l.lwz r9,24(r1) + l.lwz r8,20(r1) + l.lwz r7,16(r1) + l.lwz r5,8(r1) + + l.addi r6,r0,-3 /* Set r6 to 0xFFFFFFFD */ + l.mfspr r3,r0,17 /* Get SR value */ + l.and r3,r3,r6 /* Clear exception bit */ + l.mfspr r0,r3,17 /* Disable exceptions */ + + l.lwz r6,76(r1) /* Recover ESR */ + l.lwz r4,72(r1) /* Recover EPCR */ + l.mtspr r0,r4,0x20 /* Restore ESR */ + l.mtspr r0,r6,0x40 /* Restore EPCR */ + l.lwz r6,12(r1) + l.lwz r4,4(r1) + +L2_2: + l.lwz r11,28(r1) + l.lwz r3,0(r1) + l.addi r1,r1,80 + l.rfe + l.nop /* The document doesn't say this is + a delay slot instruction, but the + simulator doesn't work without this. */ + +.endproc ___standard_exception + .def ___standard_exception + .val . + .scl -1 + .endef + + + /** Currently, about 57 of the 64 valid address locations + are being used here. If you add code to the above + routine, make sure it isn't more than 7 instructions + or you will overflow into the reset vector. **/ + + /****************************/ + /* Reset vector static code */ + /****************************/ + .org 0x100 +.proc ___rst + .global ___rst +___rst: + /* Set the stack pointer */ + l.movhi r1,hi(_TOP_OF_MEMORY) + l.ori r1,r1,lo(_TOP_OF_MEMORY) + l.lwz r1,0(r1) /* Dereference it */ + + /* Set the frame pointer */ + l.add r2,r0,r1 + + l.mfspr r3,r0,17 /* Get SR value */ + l.ori r3,r3,2 /* Set exception enable bit */ + l.j _start /* Jump to main routine */ + l.mtspr r0,r3,17 /* Enable exceptions (DELAY) */ +.endproc ___rst + + /***********************************************************/ + /* Note: right after the reset vector, we are going to */ + /* place a table with the necessary values to initialize */ + /* the memory controller. This pointer will be set and */ + /* passed to the _start routine in r4. The first thing the */ + /* the _start routine will do is to initialize the memory */ + /* controller. The code to initialze the memory controller */ + /* is expected to be larger than the 50 some odd */ + /* instructions that are remaining here before the bus */ + /* error vector, which is why it is left to the _start */ + /* routine. */ + /***********************************************************/ + + /********************************/ + /* Bus Error vector static code */ + /********************************/ + .org 0x200 +.proc ___bus_error + .global ___bus_error +___bus_error: + l.addi r1,r1,-80 + l.sw 0(r1),r3 + l.sw 28(r1),r11 + l.movhi r11,hi(_Or1k_Interrupt_Vectors) + l.ori r11,r11,lo(_Or1k_Interrupt_Vectors) + l.lwz r11,8(r11) + l.j ___standard_exception + l.addi r3,r0,2 + +.endproc ___bus_error + + /* Put _Internal_error_Occurred and _int_reenable here */ + /* No reason to waste space...it'll be filled with 0 if */ + /* we don't... */ + + /********************************/ + /* _Internal_error_Occurred */ + /********************************/ + +.proc __Internal_error_Occurred + .def __Internal_error_Occurred + .val __Internal_error_Occurred + .scl 2 + .type 044 + .endef + .global __Internal_error_Occurred +__Internal_error_Occurred: + + l.jal __panic + l.nop + +.endproc __Internal_error_Occurred + .def __Internal_error_Occurred + .val . + .scl -1 + .endef + + + /*********************/ + /* _int_reenable */ + /*********************/ + +.proc __int_reenable + .def __int_reenable + .val __int_reenable + .scl 2 + .type 044 + .endef + .global __int_reenable +__int_reenable: + + l.mfspr r11,r0,17 + l.ori r11,r11,0x04 + l.jr r9 + l.mtspr r0,r11,17 + +.endproc __int_reenable + .def __int_reenable + .val . + .scl -1 + .endef + + /*********************&**/ + /* ___user_function */ + /************************/ + +.proc ___user_function + .def ___user_function + .val ___user_function + .scl 2 + .type 044 + .endef + .global ___user_function +___user_function: + + /* r11 contains the address to call. We can + modify r7, r8, r12, and r14 at will */ + + l.movhi r7,hi(__Thread_Dispatch_disable_level) + l.ori r7,r7,lo(__Thread_Dispatch_disable_level) + l.lwz r8,0(r7) + + l.addi r1,r1,-8 # Stack must be DWORD aligned + l.sw 0(r1),r9 # Save the return address + + l.addi r8,r8,1 # Increment __Thread_Dispatch... + l.jalr r11 + l.sw 0(r7),r8 # Disable thread dispatching + + /* Now, we need to determine if we need to + service the RTEMS environment. RTEMS tries + to draw a distinction between a RAW handler + (where this isn't necessary) and an RTEMS + handler. However, it appears almost all ISR's + will not be RAW under this definition, and + those that are will not honestly be hurt by + the 20 or so extra cycles it will take to do + the following code. If there is a very frequent + interrupt, then it should probably be hard + coded into the static routine anyway, rather + than suffer the hit of calling it indirectly */ + + /* Note: RTEMS recommends incrementing and + decrementing the _ISR_Nest_Level as well. + We are specifically not doing this because + in the Or1k architecture it is impossible + to nest interrupts. Interrupts must run to + completion before reenabling. If there is a + significant task to be done, then it should + run in a bottom half handler, similar to the + way Linux works. In theory though, even if + we do allow nested interrupts, there is no + reason for this flag, as it seems to be for + the purpose of restoring the normal stack in + place of the interrupt stack. We don't use a + separate exception stack, so this should not + be an issue for us. */ + + l.movhi r7,hi(__Thread_Dispatch_disable_level) + l.ori r7,r7,lo(__Thread_Dispatch_disable_level) + l.lwz r8,0(r7) + l.addi r8,r8,-1 # Decrement __Thread_Dispatch... + l.sw 0(r7),r8 # Memory stall likely here... + + l.sfeqi r8,0 # Skip if _Thread_Dispatch != 0 + l.bnf L4_2 + l.movhi r7,hi(__Context_Switch_necessary) + + l.ori r7,r7,lo(__Context_Switch_necessary) + l.lwz r8,0(r7) + + l.movhi r7,hi(__ISR_Signals_to_thread_executing) + l.ori r7,r7,lo(__ISR_Signals_to_thread_executing) + l.lwz r12,0(r7) + + l.sfeqi r8,0 # Skip if __Context... is false + l.bf L4_2 + l.movhi r14,hi(__Thread_Dispatch) + + l.sfeqi r12,0 # Skip if __ISR... is true + l.bnf L4_2 + l.ori r14,r14,lo(__Thread_Dispatch) + + l.jalr r14 + l.sw 0(r7),r0 # Set __ISR... to false + +L4_2: + l.lwz r9,0(r1) # Recover the return address + l.jr r9 + l.addi r1,r1,8 # Reset the stack + +.endproc ___user_function + .def ___user_function + .val . + .scl -1 + .endef + + + /* Code wasted between here and 0x300 */ + + /**************************************/ + /* Data Page Fault vector static code */ + /**************************************/ + .org 0x300 +.proc ___data_page_fault + .global ___data_page_fault +___data_page_fault: + l.addi r1,r1,-80 + l.sw 0(r1),r3 + l.sw 28(r1),r11 + l.movhi r11,hi(_Or1k_Interrupt_Vectors) + l.ori r11,r11,lo(_Or1k_Interrupt_Vectors) + l.lwz r11,12(r11) + l.j ___standard_exception + l.addi r3,r0,3 +.endproc ___data_page_fault + + /* Code wasted between here and 0x400 */ + + /*********************************************/ + /* Instruction Page Fault vector static code */ + /*********************************************/ + .org 0x400 +.proc ___insn_page_fault + .global ___insn_page_fault +___insn_page_fault: + l.addi r1,r1,-80 + l.sw 0(r1),r3 + l.sw 28(r1),r11 + l.movhi r11,hi(_Or1k_Interrupt_Vectors) + l.ori r11,r11,lo(_Or1k_Interrupt_Vectors) + l.lwz r11,16(r11) + l.j ___standard_exception + l.addi r3,r0,4 +.endproc ___insn_page_fault + + /* Code wasted between here and 0x500 */ + + /**************************************/ + /* Low Priority Interrupt static code */ + /**************************************/ + .org 0x500 +.proc ___low_priority_int + .global ___low_priority_int +___low_priority_int: + l.addi r1,r1,-80 + l.sw 0(r1),r3 + l.sw 28(r1),r11 + l.mfspr r3,r0,17 # Get the SR + l.addi r11,r0,-5 # r11 = 0xFFFFFFFB + l.and r11,r11,r3 # Clear the EIR bit + l.mtspr r0,r11,17 # Set the SR w/o INT + l.movhi r11,hi(_Or1k_Interrupt_Vectors) + l.ori r11,r11,lo(_Or1k_Interrupt_Vectors) + l.lwz r11,20(r11) + l.j ___standard_exception + l.addi r3,r0,5 +.endproc ___low_priority_int + + /* Code wasted between here and 0x600 */ + + /******************************************/ + /* Alignment Exception vector static code */ + /******************************************/ + .org 0x600 +.proc ___alignment_exception + .global ___alignment_exception +___alignment_exception: + l.addi r1,r1,-80 + l.sw 0(r1),r3 + l.sw 28(r1),r11 + l.movhi r11,hi(_Or1k_Interrupt_Vectors) + l.ori r11,r11,lo(_Or1k_Interrupt_Vectors) + l.lwz r11,24(r11) + l.j ___standard_exception + l.addi r3,r0,6 +.endproc ___alignment_exception + + /* Code wasted between here and 0x700 */ + + /******************************************/ + /* Illegal Instruction vector static code */ + /******************************************/ + .org 0x700 +.proc ___illegal_instruction + .global ___illegal_instruction +___illegal_instruction: + l.addi r1,r1,-80 + l.sw 0(r1),r3 + l.sw 28(r1),r11 + l.movhi r11,hi(_Or1k_Interrupt_Vectors) + l.ori r11,r11,lo(_Or1k_Interrupt_Vectors) + l.lwz r11,28(r11) + l.j ___standard_exception + l.addi r3,r0,7 +.endproc ___illegal_instruction + + /* Code wasted between here and 0x800 */ + + /***************************************/ + /* High Priority Interrupt static code */ + /***************************************/ + .org 0x800 +.proc ___high_priority_int + .global ___high_priority_int +___high_priority_int: + l.addi r1,r1,-80 + l.sw 0(r1),r3 + l.sw 28(r1),r11 + l.mfspr r3,r0,17 # Get the SR + l.addi r11,r0,-5 # r11 = 0xFFFFFFFB + l.and r11,r11,r3 # Clear the EIR bit + l.mtspr r0,r11,17 # Set the SR w/o INT + l.movhi r11,hi(_Or1k_Interrupt_Vectors) + l.ori r11,r11,lo(_Or1k_Interrupt_Vectors) + l.lwz r11,32(r11) + l.j ___standard_exception + l.addi r3,r0,8 +.endproc ___high_priority_int + + /* Code wasted between here and 0x900 */ + + /********************************/ + /* ITBL Miss vector static code */ + /********************************/ + .org 0x900 +.proc ___ITBL_miss_exception + .global ___ITBL_miss_exception +___ITBL_miss_exception: + l.addi r1,r1,-80 + l.sw 0(r1),r3 + l.sw 28(r1),r11 + l.movhi r11,hi(_Or1k_Interrupt_Vectors) + l.ori r11,r11,lo(_Or1k_Interrupt_Vectors) + l.lwz r11,36(r11) + l.j ___standard_exception + l.addi r3,r0,9 +.endproc ___ITBL_miss_exception + + /* Code wasted between here and 0xA00 */ + + /********************************/ + /* DTBL Miss vector static code */ + /********************************/ + .org 0xA00 +.proc ___DTBL_miss_exception + .global ___DTBL_miss_exception +___DTBL_miss_exception: + l.addi r1,r1,-80 + l.sw 0(r1),r3 + l.sw 28(r1),r11 + l.movhi r11,hi(_Or1k_Interrupt_Vectors) + l.ori r11,r11,lo(_Or1k_Interrupt_Vectors) + l.lwz r11,40(r11) + l.j ___standard_exception + l.addi r3,r0,10 +.endproc ___DTBL_miss_exception + + /* Code wasted between here and 0xB00 */ + + /**************************************/ + /* Range Exception vector static code */ + /**************************************/ + .org 0xB00 +.proc ___range_exception + .global ___range_exception +___range_exception: + l.addi r1,r1,-80 + l.sw 0(r1),r3 + l.sw 28(r1),r11 + l.movhi r11,hi(_Or1k_Interrupt_Vectors) + l.ori r11,r11,lo(_Or1k_Interrupt_Vectors) + l.lwz r11,44(r11) + l.j ___standard_exception + l.addi r3,r0,11 +.endproc ___range_exception + + /* Code wasted between here and 0xC00 */ + + /**********************************/ + /* System Call vector static code */ + /**********************************/ + .org 0xC00 +.proc ___system_call + .global ___system_call +___system_call: + l.addi r1,r1,-80 + l.sw 0(r1),r3 + l.sw 28(r1),r11 + l.movhi r11,hi(_Or1k_Interrupt_Vectors) + l.ori r11,r11,lo(_Or1k_Interrupt_Vectors) + l.lwz r11,48(r11) + l.j ___standard_exception + l.addi r3,r0,12 +.endproc ___system_call + + /* Code wasted between here and 0xD00 */ + + /**********************************/ + /* Breakpoint vector static code */ + /**********************************/ + .org 0xD00 +.proc ___breakpoint + .global ___breakpoint +___breakpoint: + + /* In keeping with the necessary requirements for + gdb to work, we are limiting this vector to + only 2 statements, which effect an immediate + return. At a later date, we may insert a debug + monitor here that will do even more, but for + now, this is all we want. */ + l.rfe + l.nop + +.endproc ___breakpoint + + /* Code wasted between here and 0xE00 */ + + /*************************************/ + /* Trap Exception vector static code */ + /*************************************/ + .org 0xE00 +.proc ___trap_exception + .global ___trap_exception +___trap_exception: + l.addi r1,r1,-80 + l.sw 0(r1),r3 + l.sw 28(r1),r11 + l.movhi r11,hi(_Or1k_Interrupt_Vectors) + l.ori r11,r11,lo(_Or1k_Interrupt_Vectors) + l.lwz r11,56(r11) + l.j ___standard_exception + l.addi r3,r0,14 +.endproc ___trap_exception + + /* Code wasted between here and 0x2000 */ + + /* Exceptions from 0xF00 to 0x1F00 are not defined */ + /* in the Or1k architecture. They should be filled */ + /* in here for other implementations. */ + + .org 0x2000 /* Start after exception vector table */ + + /*********************/ + /* start */ + /*********************/ + + /* This is where we jump to right after the reset exception + handler. The system configuration information should + be passed to us in a pointer in r4. Generally, the + reset vector will call this routine directly, and + the memory configuration information will be stored + in the ROM/Flash image. It was decided no attempt + would be made to automatically determine this + information by probing, as the scheme would be too + complex and inherently unreliable. */ + + /* Initialize strings and structures here */ +L_program: + .ascii "RTEMS_or1k\000" + .align 4 +L_argv: + .word L_program + +.proc _start + .def _start + .val _start + .scl 2 + .type 044 + .endef + .global _start +_start: + + /* Initialize the memory controller here! + Discussions with Rudi have stated that + the first few bytes of the ROM image should + contain a RAM map as opposed to trying to + figure out what to do based on probing. This + means a separate build of the OS for every + possible board configuration, but there + doesn't seem to be a better alternative. */ + + /*** FIX ME! Initialize the external memory controller! ***/ + + /* Move the data segment to RAM. Alternatively, we may + copy the text segment as well. For now, we'll assume + that the cache gives us sufficient performance that this + is not necessary. It will be very easy to add this later. + */ + l.movhi r4,hi(_data_start) + l.ori r4,r4,lo(_data_start) + l.movhi r5,hi(_BOTTOM_OF_MEMORY) + l.ori r5,r5,lo(_BOTTOM_OF_MEMORY) + l.lwz r5,0(r5) # Dereference it + l.add r5,r5,r4 # Place it in memory above the text segment + l.movhi r3,hi(_edata) + l.ori r3,r3,lo(_edata) + +L3_0: + l.lwz r6,0(r4) + l.addi r5,r5,4 + l.addi r4,r4,4 + l.sfeq r3,r4 + l.bnf L3_0 + l.sw -4(r5),r6 # Minimize write after read stalls + + /* Initialize the BSS segment */ + l.movhi r3,hi(_bss_start) + l.ori r3,r3,lo(_bss_start) + l.sub r3,r3,r4 + l.add r3,r3,r5 + l.sfleu r3,r5 + l.bf L3_2 # Check for no BSS segment! + l.nop + +L3_1: + l.sw 0(r5),r0 + l.sfeq r5,r3 + l.bnf L3_1 + l.addi r5,r5,4 + +L3_2: + /* Tell everyone where the heap begins */ + l.movhi r4,hi(__mem_end) + l.ori r4,r4,lo(__mem_end) + l.sw 0(r4),r5 + + /* Due to what I consider a bug in RTEMS, the entire + heap must be zeroed. I think this is the dumbest thing + I've ever heard, but whatever turns them on. I'd rather + see the code which depends on this behavior fixed. I + myself have never written code which assumes zeroes + will be returned from memory allocated from the heap. + Anyway, if I don't do it here, I have to set a flag in + the CPU structure which then will do it anyway, but + from less efficient C code! Zero from here to the + stack pointer... One day when I'm old and gray maybe + I'll set this to random values instead and fix + whatever breaks. */ + + l.sw 0(r5),r0 + l.sfeq r5,r1 + l.bnf L3_3 + l.addi r5,r5,4 + +L3_3: + l.addi r3,r0,1 /* Set argc to 1 */ + l.movhi r4,hi(L_argv) /* Initialize argv */ + l.ori r4,r4,lo(L_argv) + l.addi r5,r5,0 /* Set envp to NULL */ + + l.mfspr r11,r0,17 /* Get SR value */ + l.ori r11,r11,0x4 /* Set interrupt enable bit */ + l.jal _boot_card /* Boot up the card...run the OS */ + l.mtspr r0,r11,17 /* Enable exceptions (DELAY) */ + + /* We're done. We exited normally. Shut down. */ + l.jal __exit + l.nop + +.endproc _start + .def _start + .val . + .scl -1 + .endef + + END_CODE + diff --git a/c/src/lib/libbsp/or32/orp/startup/.cvsignore b/c/src/lib/libbsp/or32/orp/startup/.cvsignore new file mode 100644 index 0000000000..282522db03 --- /dev/null +++ b/c/src/lib/libbsp/or32/orp/startup/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/c/src/lib/libbsp/or32/orp/startup/bspclean.c b/c/src/lib/libbsp/or32/orp/startup/bspclean.c new file mode 100644 index 0000000000..64a881b22a --- /dev/null +++ b/c/src/lib/libbsp/or32/orp/startup/bspclean.c @@ -0,0 +1,25 @@ +/* bsp_cleanup() + * + * This routine normally is part of start.s and usually returns + * control to a monitor. + * + * INPUT: NONE + * + * OUTPUT: NONE + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include +#include + +void bsp_cleanup( void ) +{ +} diff --git a/c/src/lib/libbsp/or32/orp/startup/bspstart.c b/c/src/lib/libbsp/or32/orp/startup/bspstart.c new file mode 100644 index 0000000000..85e1f4ff3f --- /dev/null +++ b/c/src/lib/libbsp/or32/orp/startup/bspstart.c @@ -0,0 +1,122 @@ +/* + * 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. + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * This file adapted from no_bsp board library of the RTEMS distribution. + * The body has been modified for the Bender Or1k implementation by + * Chris Ziomkowski. + */ + +#include +#include + +#include + +#include +extern int _mem_end; + +/* + * 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; + +/* + * Use the shared implementations of the following routines + */ + +void bsp_postdriver_hook(void); +void bsp_libc_init( void *, unsigned32, int ); + +/* + * 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) +{ + rtems_unsigned32 heap_start; + + heap_start = (rtems_unsigned32) _mem_end; + if (heap_start & (CPU_ALIGNMENT-1)) + heap_start = (heap_start + CPU_ALIGNMENT) & ~(CPU_ALIGNMENT-1); + + bsp_libc_init((void *) heap_start, 64 * 1024, 0); + +#ifdef RTEMS_DEBUG + rtems_debug_enable( RTEMS_DEBUG_ALL_MASK ); +#endif +} + +/* + * bsp_start + * + * This routine does the bulk of the system initialization. + */ + +void bsp_start( void ) +{ + /* + * Allocate the memory for the RTEMS Work Space. This can come from + * a variety of places: hard coded address, malloc'ed from outside + * RTEMS world (e.g. simulator or primitive memory manager), or (as + * typically done by stock BSPs) by subtracting the required amount + * of work space from the last physical address on the CPU board. + */ + + /* + * Need to "allocate" the memory for the RTEMS Workspace and + * tell the RTEMS configuration where it is. This memory is + * not malloc'ed. It is just "pulled from the air". + */ + + BSP_Configuration.work_space_start = _mem_end; + _mem_end += BSP_Configuration.work_space_size + 512; + ( BSP_Configuration.work_space_size + 512 ); + + BSP_Configuration.work_space_start = (void *) ((unsigned int)((char *)BSP_Configuration.work_space_start + CPU_ALIGNMENT) & ~(CPU_ALIGNMENT-1)); + + /* + * initialize the CPU table for this BSP + */ + + Cpu_table.pretasking_hook = bsp_pretasking_hook; /* init libc, etc. */ + Cpu_table.postdriver_hook = bsp_postdriver_hook; + Cpu_table.do_zero_of_workspace = FALSE; + Cpu_table.interrupt_stack_size = CONFIGURE_INTERRUPT_STACK_MEMORY; + + /* + * Start RTEMS + */ + + rtems_initialize_executive( &BSP_Configuration, &Cpu_table ); + + bsp_cleanup(); + + return 0; +} diff --git a/c/src/lib/libbsp/or32/orp/startup/linkcmds b/c/src/lib/libbsp/or32/orp/startup/linkcmds new file mode 100644 index 0000000000..72eb039092 --- /dev/null +++ b/c/src/lib/libbsp/or32/orp/startup/linkcmds @@ -0,0 +1,63 @@ +/* + * This file contains directives for the GNU linker which are specific + * to the NO_CPU NO_BSP BOARD. + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +MEMORY + { + ram : org = 0x0, l = 1M + } + +SECTIONS +{ + .text 0x0 : + { + text_start = . ; + _text_start = . ; + *(.text) + . = ALIGN (16); + + *(.eh_fram) + . = ALIGN (16); + + /* + * C++ constructors + */ + __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__ = .; + _etext = ALIGN( 0x10 ) ; + } + .data ADDR( .text ) + SIZEOF( .text ): + { + data_start = . ; + _data_start = . ; + *(.data) + _edata = ALIGN( 0x10 ) ; + } + .bss ADDR( .data ) + SIZEOF( .data ): + { + bss_start = . ; + _bss_start = . ; + *(.bss) + *(COMMON) + end = . ; + __end = . ; + } +} diff --git a/c/src/lib/libbsp/or32/orp/startup/main.c b/c/src/lib/libbsp/or32/orp/startup/main.c new file mode 100644 index 0000000000..2c06bd1ffa --- /dev/null +++ b/c/src/lib/libbsp/or32/orp/startup/main.c @@ -0,0 +1,37 @@ +/* main() + * + * This is the entry point for the application. It calls + * the bsp_start routine to the actual dirty work. + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include +#include + +int main( + int argc, + char **argv, + char **environp +) +{ + extern void bsp_start( int, char**, char ** ); + + bsp_start( argc, argv, environp ); + + /* + * May be able to return to the "crt/start.s" code but also + * may not be able to. Do something here which is board dependent. + */ + + rtems_fatal_error_occurred( 0 ); + + return 0; /* just to satisfy the native compiler */ +} diff --git a/c/src/lib/libbsp/or32/orp/startup/setvec.c b/c/src/lib/libbsp/or32/orp/startup/setvec.c new file mode 100644 index 0000000000..e12049be19 --- /dev/null +++ b/c/src/lib/libbsp/or32/orp/startup/setvec.c @@ -0,0 +1,43 @@ +/* set_vector + * + * This routine installs an interrupt vector on the target Board/CPU. + * This routine is allowed to be as board dependent as necessary. + * + * 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-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include +#include + +no_cpu_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 */ +) +{ + no_cpu_isr_entry previous_isr; + + if ( type ) + rtems_interrupt_catch( handler, vector, (rtems_isr_entry *) &previous_isr ); + else { + /* XXX: install non-RTEMS ISR as "raw" interupt */ + } + return previous_isr; +} + diff --git a/c/src/lib/libbsp/or32/orp/timer/.cvsignore b/c/src/lib/libbsp/or32/orp/timer/.cvsignore new file mode 100644 index 0000000000..282522db03 --- /dev/null +++ b/c/src/lib/libbsp/or32/orp/timer/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/c/src/lib/libbsp/or32/orp/timer/Makefile.am b/c/src/lib/libbsp/or32/orp/timer/Makefile.am new file mode 100644 index 0000000000..dd37437644 --- /dev/null +++ b/c/src/lib/libbsp/or32/orp/timer/Makefile.am @@ -0,0 +1,34 @@ +## +## $Id$ +## + + +VPATH = @srcdir@:@srcdir@/../../../shared + +PGM = $(ARCH)/timer.rel + +C_FILES = timer.c timerisr.c +C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o) + +OBJS = $(C_O_FILES) + +include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg +include $(top_srcdir)/../../../../../../automake/compile.am +include $(top_srcdir)/../../../../../../automake/lib.am + +# +# (OPTIONAL) Add local stuff here using += +# + +$(PGM): $(OBJS) + $(make-rel) + +# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile + +all-local: $(ARCH) $(OBJS) $(PGM) + +.PRECIOUS: $(PGM) + +EXTRA_DIST = timer.c timerisr.c + +include $(top_srcdir)/../../../../../../automake/local.am diff --git a/c/src/lib/libbsp/or32/orp/timer/timer.c b/c/src/lib/libbsp/or32/orp/timer/timer.c new file mode 100644 index 0000000000..436e44a918 --- /dev/null +++ b/c/src/lib/libbsp/or32/orp/timer/timer.c @@ -0,0 +1,104 @@ +/* timer.c + * + * This file manages the benchmark timer used by the RTEMS Timing Test + * Suite. Each measured time period is demarcated by calls to + * Timer_initialize() and Read_timer(). Read_timer() usually returns + * the number of microseconds since Timer_initialize() exitted. + * + * NOTE: It is important that the timer start/stop overhead be + * determined when porting or modifying this code. + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include +#include + +rtems_unsigned32 Timer_interrupts; +rtems_boolean Timer_driver_Find_average_overhead; + +void Timer_initialize( void ) +{ + + /* + * Timer has never overflowed. This may not be necessary on some + * implemenations of timer but .... + */ + + Timer_interrupts = 0; + + /* + * Somehow start the timer + */ +} + +/* + * The following controls the behavior of Read_timer(). + * + * 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 */ + +int Read_timer( void ) +{ + rtems_unsigned32 clicks; + rtems_unsigned32 total; + + /* + * Read the timer and see how many clicks it has been since we started. + */ + + clicks = 0; /* XXX: read some HW here */ + + /* + * 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 = clicks * 0; + + if ( Timer_driver_Find_average_overhead == 1 ) + return total; /* in XXX microsecond units */ + else { + if ( total < LEAST_VALID ) + return 0; /* below timer resolution */ + /* + * Somehow convert total into microseconds + */ + 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/or32/orp/timer/timerisr.c b/c/src/lib/libbsp/or32/orp/timer/timerisr.c new file mode 100644 index 0000000000..f492761a05 --- /dev/null +++ b/c/src/lib/libbsp/or32/orp/timer/timerisr.c @@ -0,0 +1,36 @@ +/* timerisr.s + * + * If required this ISR is used to bump a count of interval "overflow" + * interrupts which have occurred since the timer was started. The + * number of overflows is taken into account in the Read_timer() + * routine if necessary. + * + * To reduce overhead this is best to be the "rawest" hardware interupt + * handler you can write. This should be the only interrupt which can + * occur during the measured time period. + * + * NOTE: This file is USUALLY in assembly and is LEAN AND MEAN. + * Any code in this isr is pure overhead which can perturb + * the accuracy of the Timing Test Suite. + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include + +extern rtems_unsigned32 _Timer_interrupts; + +void timerisr( void ) +{ + /* + * _Timer_interrupts += TIMER_BETWEEN_OVERFLOWS (usually in microseconds) + * return from interrupt + */ +} diff --git a/c/src/lib/libbsp/or32/orp/times b/c/src/lib/libbsp/or32/orp/times new file mode 100644 index 0000000000..2ac0b9ee22 --- /dev/null +++ b/c/src/lib/libbsp/or32/orp/times @@ -0,0 +1,194 @@ +# +# Timing Test Suite Results for the NO_BSP +# +# NOTE: This is just a template. The times are irrelevant since this BSP +# can only be compiled -- not executed. +# +# $Id$ +# + +Board: +CPU: include coprocessor if applicable +Clock Speed: +Memory Configuration: SRAM, DRAM, cache, etc +Wait States: + +Times Reported in: cycles, microseconds, etc +Timer Source: Count Down Timer, on-CPU cycle counter, etc + +Column X: +Column Y: + +# DESCRIPTION A B +== ================================================================= ==== ==== + 1 rtems_semaphore_create 20 + rtems_semaphore_delete 21 + rtems_semaphore_obtain: available 15 + rtems_semaphore_obtain: not available -- NO_WAIT 15 + rtems_semaphore_release: no waiting tasks 16 + + 2 rtems_semaphore_obtain: not available -- caller blocks 62 + + 3 rtems_semaphore_release: task readied -- preempts caller 55 + + 4 rtems_task_restart: blocked task -- preempts caller 77 + rtems_task_restart: ready task -- preempts caller 70 + rtems_semaphore_release: task readied -- returns to caller 25 + rtems_task_create 57 + rtems_task_start 31 + rtems_task_restart: suspended task -- returns to caller 36 + rtems_task_delete: suspended task 47 + rtems_task_restart: ready task -- returns to caller 37 + rtems_task_restart: blocked task -- returns to caller 46 + rtems_task_delete: blocked task 50 + + 5 rtems_task_suspend: calling task 51 + rtems_task_resume: task readied -- preempts caller 49 + + 6 rtems_task_restart: calling task 59 + rtems_task_suspend: returns to caller 18 + rtems_task_resume: task readied -- returns to caller 19 + rtems_task_delete: ready task 50 + + 7 rtems_task_restart: suspended task -- preempts caller 70 + + 8 rtems_task_set_priority: obtain current priority 12 + rtems_task_set_priority: returns to caller 27 + rtems_task_mode: obtain current mode 5 + rtems_task_mode: no reschedule 5 + rtems_task_mode: reschedule -- returns to caller 8 + rtems_task_mode: reschedule -- preempts caller 39 + rtems_task_set_note 13 + rtems_task_get_note 13 + rtems_clock_set 33 + rtems_clock_get 3 + + 9 rtems_message_queue_create 110 + rtems_message_queue_send: no waiting tasks 37 + rtems_message_queue_urgent: no waiting tasks 37 + rtems_message_queue_receive: available 31 + rtems_message_queue_flush: no messages flushed 12 + rtems_message_queue_flush: messages flushed 16 + rtems_message_queue_delete 26 + +10 rtems_message_queue_receive: not available -- NO_WAIT 15 + rtems_message_queue_receive: not available -- caller blocks 62 + +11 rtems_message_queue_send: task readied -- preempts caller 72 + +12 rtems_message_queue_send: task readied -- returns to caller 39 + +13 rtems_message_queue_urgent: task readied -- preempts caller 72 + +14 rtems_message_queue_urgent: task readied -- returns to caller 39 + +15 rtems_event_receive: obtain current events 1 + rtems_event_receive: not available -- NO_WAIT 12 + rtems_event_receive: not available -- caller blocks 56 + rtems_event_send: no task readied 12 + rtems_event_receive: available 12 + rtems_event_send: task readied -- returns to caller 24 + +16 rtems_event_send: task readied -- preempts caller 55 + +17 rtems_task_set_priority: preempts caller 62 + +18 rtems_task_delete: calling task 83 + +19 rtems_signal_catch 9 + rtems_signal_send: returns to caller 15 + rtems_signal_send: signal to self 18 + exit ASR overhead: returns to calling task 22 + exit ASR overhead: returns to preempting task 49 + +20 rtems_partition_create 35 + rtems_region_create 23 + rtems_partition_get_buffer: available 15 + rtems_partition_get_buffer: not available 13 + rtems_partition_return_buffer 18 + rtems_partition_delete 16 + rtems_region_get_segment: available 22 + rtems_region_get_segment: not available -- NO_WAIT 21 + rtems_region_return_segment: no waiting tasks 19 + rtems_region_get_segment: not available -- caller blocks 64 + rtems_region_return_segment: task readied -- preempts caller 74 + rtems_region_return_segment: task readied -- returns to caller 44 + rtems_region_delete 16 + rtems_io_initialize 2 + rtems_io_open 1 + rtems_io_close 1 + rtems_io_read 1 + rtems_io_write 1 + rtems_io_control 1 + +21 rtems_task_ident 149 + rtems_message_queue_ident 145 + rtems_semaphore_ident 156 + rtems_partition_ident 145 + rtems_region_ident 148 + rtems_port_ident 145 + rtems_timer_ident 145 + rtems_rate_monotonic_ident 145 + +22 rtems_message_queue_broadcast: task readied -- returns to caller 42 + rtems_message_queue_broadcast: no waiting tasks 17 + rtems_message_queue_broadcast: task readied -- preempts caller 78 + +23 rtems_timer_create 14 + rtems_timer_fire_after: inactive 22 + rtems_timer_fire_after: active 24 + rtems_timer_cancel: active 15 + rtems_timer_cancel: inactive 13 + rtems_timer_reset: inactive 21 + rtems_timer_reset: active 23 + rtems_timer_fire_when: inactive 34 + rtems_timer_fire_when: active 34 + rtems_timer_delete: active 19 + rtems_timer_delete: inactive 17 + rtems_task_wake_when 69 + +24 rtems_task_wake_after: yield -- returns to caller 9 + rtems_task_wake_after: yields -- preempts caller 45 + +25 rtems_clock_tick 4 + +26 _ISR_Disable 0 + _ISR_Flash 1 + _ISR_Enable 1 + _Thread_Disable_dispatch 0 + _Thread_Enable_dispatch 7 + _Thread_Set_state 11 + _Thread_Disptach (NO FP) 31 + context switch: no floating point contexts 21 + context switch: self 10 + context switch: to another task 10 + context switch: restore 1st FP task 25 + fp context switch: save idle, restore idle 31 + fp context switch: save idle, restore initialized 19 + fp context switch: save initialized, restore initialized 20 + _Thread_Resume 7 + _Thread_Unblock 7 + _Thread_Ready 9 + _Thread_Get 4 + _Semaphore_Get 2 + _Thread_Get: invalid id 0 + +27 interrupt entry overhead: returns to interrupted task 6 + interrupt exit overhead: returns to interrupted task 6 + interrupt entry overhead: returns to nested interrupt 6 + interrupt exit overhead: returns to nested interrupt 5 + interrupt entry overhead: returns to preempting task 7 + interrupt exit overhead: returns to preempting task 36 + +28 rtems_port_create 16 + rtems_port_external_to_internal 11 + rtems_port_internal_to_external 11 + rtems_port_delete 16 + +29 rtems_rate_monotonic_create 15 + rtems_rate_monotonic_period: initiate period -- returns to caller 21 + rtems_rate_monotonic_period: obtain status 13 + rtems_rate_monotonic_cancel 16 + rtems_rate_monotonic_delete: inactive 18 + rtems_rate_monotonic_delete: active 20 + rtems_rate_monotonic_period: conclude periods -- caller blocks 53 diff --git a/c/src/lib/libbsp/or32/orp/wrapup/.cvsignore b/c/src/lib/libbsp/or32/orp/wrapup/.cvsignore new file mode 100644 index 0000000000..282522db03 --- /dev/null +++ b/c/src/lib/libbsp/or32/orp/wrapup/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/c/src/lib/libbsp/or32/orp/wrapup/Makefile.am b/c/src/lib/libbsp/or32/orp/wrapup/Makefile.am new file mode 100644 index 0000000000..d094f1281b --- /dev/null +++ b/c/src/lib/libbsp/or32/orp/wrapup/Makefile.am @@ -0,0 +1,27 @@ +## +## $Id$ +## + +BSP_FILES = startup clock console timer + +include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg +include $(top_srcdir)/../../../../../../automake/compile.am +include $(top_srcdir)/../../../../../../automake/lib.am + +# bummer; have to use $foreach since % pattern subst rules only replace 1x +OBJS = $(foreach piece, $(BSP_FILES), $(wildcard ../$(piece)/$(ARCH)/*.o)) \ + $(wildcard ../../../../libcpu/$(RTEMS_CPU)/$(RTEMS_CPU_MODEL)/$(ARCH)/*.o) \ + $(foreach piece, $(GENERIC_FILES), ../../../$(piece)/$(ARCH)/$(piece).rel) + +LIB = $(ARCH)/libbsp.a + +# +# (OPTIONAL) Add local stuff here using += +# + +$(LIB): ${OBJS} + $(make-library) + +all-local: ${ARCH} $(LIB) + +include $(top_srcdir)/../../../../../../automake/local.am -- cgit v1.2.3