From 16a384cfb161f6a3dbcd69fc3b788b6dbc229669 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Fri, 23 Apr 1999 16:35:11 +0000 Subject: New BSP from Tony R. Ambardar from the University of British Columbia. The BSP is for: Yes, this is the "entry model" of a series of boards from Technologic Systems. Costs <$200 I believe. They have a WWW page at www.t-systems.com. I am letting them know about the availability of this BSP too. --- c/src/lib/libbsp/i386/ts_386ex/Makefile.in | 31 + c/src/lib/libbsp/i386/ts_386ex/README | 43 + c/src/lib/libbsp/i386/ts_386ex/bsp_specs | 23 + c/src/lib/libbsp/i386/ts_386ex/clock/Makefile.in | 70 ++ c/src/lib/libbsp/i386/ts_386ex/clock/ckinit.c | 191 ++++ c/src/lib/libbsp/i386/ts_386ex/clock/rtc.c | 226 +++++ c/src/lib/libbsp/i386/ts_386ex/console/Makefile.in | 74 ++ c/src/lib/libbsp/i386/ts_386ex/console/console.c | 399 ++++++++ c/src/lib/libbsp/i386/ts_386ex/include/Makefile.in | 50 + c/src/lib/libbsp/i386/ts_386ex/include/bsp.h | 186 ++++ c/src/lib/libbsp/i386/ts_386ex/include/coverhd.h | 104 ++ c/src/lib/libbsp/i386/ts_386ex/include/wd80x3.h | 123 +++ c/src/lib/libbsp/i386/ts_386ex/network/Makefile.in | 66 ++ c/src/lib/libbsp/i386/ts_386ex/network/ne2000.c | 1041 ++++++++++++++++++++ c/src/lib/libbsp/i386/ts_386ex/start/80386ex.h | 254 +++++ c/src/lib/libbsp/i386/ts_386ex/start/80386ex.inc | 252 +++++ c/src/lib/libbsp/i386/ts_386ex/start/Makefile.in | 72 ++ c/src/lib/libbsp/i386/ts_386ex/start/macros.inc | 115 +++ c/src/lib/libbsp/i386/ts_386ex/start/start.S | 501 ++++++++++ c/src/lib/libbsp/i386/ts_386ex/start/ts_1325.inc | 50 + c/src/lib/libbsp/i386/ts_386ex/startup/Makefile.in | 79 ++ c/src/lib/libbsp/i386/ts_386ex/startup/README | 17 + c/src/lib/libbsp/i386/ts_386ex/startup/bspstart.c | 161 +++ c/src/lib/libbsp/i386/ts_386ex/startup/linkcmds | 124 +++ c/src/lib/libbsp/i386/ts_386ex/startup/setvec.c | 55 ++ c/src/lib/libbsp/i386/ts_386ex/timer/Makefile.in | 70 ++ c/src/lib/libbsp/i386/ts_386ex/timer/timer.c | 195 ++++ c/src/lib/libbsp/i386/ts_386ex/timer/timerisr.S | 40 + c/src/lib/libbsp/i386/ts_386ex/tools/Makefile.in | 26 + c/src/lib/libbsp/i386/ts_386ex/tools/README | 68 ++ c/src/lib/libbsp/i386/ts_386ex/tools/coff2bin | 23 + .../libbsp/i386/ts_386ex/tools/dos_sup/loader.com | Bin 0 -> 934 bytes .../ts_386ex/tools/dos_sup/loader_hybrid_com.asm | 575 +++++++++++ .../libbsp/i386/ts_386ex/tools/dos_sup/ts1325.inc | 48 + .../i386/ts_386ex/tools/ts_1325_ada/Makefile | 41 + .../ts_386ex/tools/ts_1325_ada/Makefile.ts_386ex | 41 + .../i386/ts_386ex/tools/ts_1325_ada/i386_ports.adb | 29 + .../i386/ts_386ex/tools/ts_1325_ada/i386_ports.ads | 47 + .../libbsp/i386/ts_386ex/tools/ts_1325_ada/init.c | 86 ++ .../ts_386ex/tools/ts_1325_ada/ts1325-button.adb | 22 + .../ts_386ex/tools/ts_1325_ada/ts1325-button.ads | 22 + .../i386/ts_386ex/tools/ts_1325_ada/ts1325-led.adb | 46 + .../i386/ts_386ex/tools/ts_1325_ada/ts1325-led.ads | 26 + .../ts_386ex/tools/ts_1325_ada/ts1325-parallel.adb | 13 + .../ts_386ex/tools/ts_1325_ada/ts1325-parallel.ads | 21 + .../i386/ts_386ex/tools/ts_1325_ada/ts1325.ads | 2 + .../ts_386ex/tools/ts_1325_ada/ts1325_test.adb | 115 +++ c/src/lib/libbsp/i386/ts_386ex/wrapup/Makefile.in | 70 ++ 48 files changed, 5933 insertions(+) create mode 100644 c/src/lib/libbsp/i386/ts_386ex/Makefile.in create mode 100644 c/src/lib/libbsp/i386/ts_386ex/README create mode 100644 c/src/lib/libbsp/i386/ts_386ex/bsp_specs create mode 100644 c/src/lib/libbsp/i386/ts_386ex/clock/Makefile.in create mode 100644 c/src/lib/libbsp/i386/ts_386ex/clock/ckinit.c create mode 100644 c/src/lib/libbsp/i386/ts_386ex/clock/rtc.c create mode 100644 c/src/lib/libbsp/i386/ts_386ex/console/Makefile.in create mode 100644 c/src/lib/libbsp/i386/ts_386ex/console/console.c create mode 100644 c/src/lib/libbsp/i386/ts_386ex/include/Makefile.in create mode 100644 c/src/lib/libbsp/i386/ts_386ex/include/bsp.h create mode 100644 c/src/lib/libbsp/i386/ts_386ex/include/coverhd.h create mode 100644 c/src/lib/libbsp/i386/ts_386ex/include/wd80x3.h create mode 100644 c/src/lib/libbsp/i386/ts_386ex/network/Makefile.in create mode 100644 c/src/lib/libbsp/i386/ts_386ex/network/ne2000.c create mode 100644 c/src/lib/libbsp/i386/ts_386ex/start/80386ex.h create mode 100644 c/src/lib/libbsp/i386/ts_386ex/start/80386ex.inc create mode 100644 c/src/lib/libbsp/i386/ts_386ex/start/Makefile.in create mode 100644 c/src/lib/libbsp/i386/ts_386ex/start/macros.inc create mode 100644 c/src/lib/libbsp/i386/ts_386ex/start/start.S create mode 100644 c/src/lib/libbsp/i386/ts_386ex/start/ts_1325.inc create mode 100644 c/src/lib/libbsp/i386/ts_386ex/startup/Makefile.in create mode 100644 c/src/lib/libbsp/i386/ts_386ex/startup/README create mode 100644 c/src/lib/libbsp/i386/ts_386ex/startup/bspstart.c create mode 100644 c/src/lib/libbsp/i386/ts_386ex/startup/linkcmds create mode 100644 c/src/lib/libbsp/i386/ts_386ex/startup/setvec.c create mode 100644 c/src/lib/libbsp/i386/ts_386ex/timer/Makefile.in create mode 100644 c/src/lib/libbsp/i386/ts_386ex/timer/timer.c create mode 100644 c/src/lib/libbsp/i386/ts_386ex/timer/timerisr.S create mode 100644 c/src/lib/libbsp/i386/ts_386ex/tools/Makefile.in create mode 100644 c/src/lib/libbsp/i386/ts_386ex/tools/README create mode 100755 c/src/lib/libbsp/i386/ts_386ex/tools/coff2bin create mode 100644 c/src/lib/libbsp/i386/ts_386ex/tools/dos_sup/loader.com create mode 100644 c/src/lib/libbsp/i386/ts_386ex/tools/dos_sup/loader_hybrid_com.asm create mode 100644 c/src/lib/libbsp/i386/ts_386ex/tools/dos_sup/ts1325.inc create mode 100644 c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/Makefile create mode 100644 c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/Makefile.ts_386ex create mode 100644 c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/i386_ports.adb create mode 100644 c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/i386_ports.ads create mode 100644 c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/init.c create mode 100644 c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/ts1325-button.adb create mode 100644 c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/ts1325-button.ads create mode 100644 c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/ts1325-led.adb create mode 100644 c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/ts1325-led.ads create mode 100644 c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/ts1325-parallel.adb create mode 100644 c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/ts1325-parallel.ads create mode 100644 c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/ts1325.ads create mode 100644 c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/ts1325_test.adb create mode 100644 c/src/lib/libbsp/i386/ts_386ex/wrapup/Makefile.in (limited to 'c/src/lib/libbsp/i386') diff --git a/c/src/lib/libbsp/i386/ts_386ex/Makefile.in b/c/src/lib/libbsp/i386/ts_386ex/Makefile.in new file mode 100644 index 0000000000..29cc2940c6 --- /dev/null +++ b/c/src/lib/libbsp/i386/ts_386ex/Makefile.in @@ -0,0 +1,31 @@ +# +# $Id$ +# + +@SET_MAKE@ +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +top_builddir = ../../../../../.. +subdir = c/src/lib/libbsp/i386/ts_386ex + +INSTALL = @INSTALL@ + +RTEMS_ROOT = $(top_srcdir)/@RTEMS_TOPdir@ +PROJECT_ROOT = @PROJECT_ROOT@ + +VPATH = @srcdir@ + +include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg +include $(RTEMS_ROOT)/make/directory.cfg + +# We only build the Network library if HAS_NETWORKING was defined +NETWORK_yes_V = network +NETWORK = $(NETWORK_$(HAS_NETWORKING)_V) + +# wrapup is the one that actually builds and installs the library +# from the individual .rel files built in other directories +SUB_DIRS=include start startup clock console timer $(NETWORK) wrapup + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status diff --git a/c/src/lib/libbsp/i386/ts_386ex/README b/c/src/lib/libbsp/i386/ts_386ex/README new file mode 100644 index 0000000000..b164be92d0 --- /dev/null +++ b/c/src/lib/libbsp/i386/ts_386ex/README @@ -0,0 +1,43 @@ +# +# $Id$ +# + +This BSP is for the Technologic Systems TS-1325, an i386EX PC/AT +compatible SBC equipped with 2 standard serial ports and a parallel +port suitable for general digital I/O. It comes with 2MB RAM and 1MB +Flash ROM. Additional information is available at the TS web site: +http://www.t-systems.com. + +The BSP uses software floating-point emulation, so one must build the +cross-compilation tools with this support. The BSP also supports the +on-board RTC, and an NE2000 compatible network card. It has been used +successfully with C (gcc-2.8.1) and Ada95 (gnat-3.11p), including +networking applications in both languages. + +The TS-1325 runs a version of DOS, and should be configured with a RAM +disk and Zmodem software (see WWW site). RTEMS executables are loaded +and run in DOS conventional memory, giving a 600K file-size limit. The +1MB extended memory is used for the RTEMS workspace, heap, stack and +BSS. Console output is to COM2 @ 115200 baud, 8-N-1. The high baud +rate is needed to speed up serial-line Zmodem file transfers. The +TS-1325 DOS console I/O is by default 9600 baud, and should be changed +to 115200 baud (see WWW site). + +A typical development cycle involves these steps: + +1. Cross-compile the application, yielding a COFF executable. Convert this + to raw binary format, using objcopy or the coff2bin script (see the + tools subdirectory in the BSP). + +2. Use Zmodem to download the raw exec to the TS-1325's ram-disk + (faster than the A: flash disk). A terminal program supporting + Zmodem is needed on the host e.g. minicom under Linux. + +3. Use the DOS-based RTEMS loader "loader.com" (see tools + subdirectory) to load and run the executable. + +Additional documentation and support software is in the tools BSP subdirectory. + +Happy Coding! + +Tony Ambardar, 4/21/99 diff --git a/c/src/lib/libbsp/i386/ts_386ex/bsp_specs b/c/src/lib/libbsp/i386/ts_386ex/bsp_specs new file mode 100644 index 0000000000..64ef6d2731 --- /dev/null +++ b/c/src/lib/libbsp/i386/ts_386ex/bsp_specs @@ -0,0 +1,23 @@ +%rename cpp old_cpp +%rename lib old_lib +%rename endfile old_endfile +%rename startfile old_startfile +%rename link old_link + +*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}} + +*startfile: +%{!qrtems: %(old_startfile)} %{qrtems: \ +%{!qrtems_debug: start.o%s} \ +%{qrtems_debug: start_g.o%s}} + +*link: +%{!qrtems: %(old_link)} %{qrtems: -dc -dp -N -e _init_i386ex} + diff --git a/c/src/lib/libbsp/i386/ts_386ex/clock/Makefile.in b/c/src/lib/libbsp/i386/ts_386ex/clock/Makefile.in new file mode 100644 index 0000000000..ae44755dc5 --- /dev/null +++ b/c/src/lib/libbsp/i386/ts_386ex/clock/Makefile.in @@ -0,0 +1,70 @@ +# +# $Id$ +# + +@SET_MAKE@ +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +top_builddir = ../../../../../../.. +subdir = c/src/lib/libbsp/i386/ts_386ex/clock + +INSTALL = @INSTALL@ + +RTEMS_ROOT = $(top_srcdir)/@RTEMS_TOPdir@ +PROJECT_ROOT = @PROJECT_ROOT@ + +VPATH = @srcdir@ + +PGM=${ARCH}/clock.rel + +# C source names, if any, go here -- minus the .c +C_PIECES=ckinit rtc +C_FILES=$(C_PIECES:%=%.c) +C_O_FILES=$(C_PIECES:%=${ARCH}/%.o) + +H_FILES= + +# Assembly source names, if any, go here -- minus the .S +S_PIECES= +S_FILES=$(S_PIECES:%=%.S) +S_O_FILES=$(S_FILES:%.S=${ARCH}/%.o) + +SRCS=$(C_FILES) $(CC_FILES) $(H_FILES) $(S_FILES) +OBJS=$(C_O_FILES) $(CC_O_FILES) $(S_O_FILES) + +include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg +include $(RTEMS_ROOT)/make/leaf.cfg + +# +# (OPTIONAL) Add local stuff here using += +# + +DEFINES += +CPPFLAGS += +CFLAGS += + +LD_PATHS += +LD_LIBS += +LDFLAGS += + +# +# Add your list of files to delete here. The config files +# already know how to delete some stuff, so you may want +# to just run 'make clean' first to see what gets missed. +# 'make clobber' already includes 'make clean' +# + +CLEAN_ADDITIONS += +CLOBBER_ADDITIONS += + +${PGM}: ${SRCS} ${OBJS} + $(make-rel) + +all: ${ARCH} $(SRCS) $(PGM) + +# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile +install: all + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status diff --git a/c/src/lib/libbsp/i386/ts_386ex/clock/ckinit.c b/c/src/lib/libbsp/i386/ts_386ex/clock/ckinit.c new file mode 100644 index 0000000000..80b644b5a4 --- /dev/null +++ b/c/src/lib/libbsp/i386/ts_386ex/clock/ckinit.c @@ -0,0 +1,191 @@ +/* Clock_initialize + * + * This routine initializes the Timer/Counter on the Intel + * 386ex evaluation board. + * + * The tick frequency is 1 millisecond. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * 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 + +rtems_unsigned32 Clock_isrs; /* ISRs until next tick */ +static rtems_unsigned32 Clock_initial_isr_value; + +volatile rtems_unsigned32 Clock_driver_ticks; + +void Clock_exit( void ); + +/* + * These are set by clock driver during its init + */ + +rtems_device_major_number rtems_clock_major = ~0; +rtems_device_major_number rtems_clock_minor = 0; + +/* + * This is the ISR handler. + */ + +void Clock_isr() +{ + /* enable_tracing(); */ + Clock_driver_ticks += 1; + if ( Clock_isrs == 1 ) { + rtems_clock_tick(); + Clock_isrs = Clock_initial_isr_value; /* BSP_Configuration.microseconds_per_tick / 1000;*/ + } + else + Clock_isrs -= 1; +} + +void ClockOff(const rtems_irq_connect_data* unused) +{ + outport_byte (TIMER_CONFIG, 0x80 ); /* disable the counter timer */ +} + +void ClockOn(const rtems_irq_connect_data* unused) +{ + outport_byte (TIMER_CONFIG, 0x00 ); /* enable the counter timer */ +} + +int ClockIsOn(const rtems_irq_connect_data* unused) +{ + return ((i8259s_cache & 0x1) == 0); +} + +static rtems_irq_connect_data clockIrqData = {BSP_PERIODIC_TIMER, + Clock_isr, + ClockOn, + ClockOff, + ClockIsOn}; + + +rtems_device_driver Clock_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *pargp +) +{ + unsigned timer_counter_init_value; + unsigned char clock_lsb, clock_msb; + +#ifdef BSP_DEBUG + printk("Initializing clock driver in Clock_initialize().\n"); +#endif + +#ifdef LOAD_RTC_AT_START + /* Initialize clock from on-board real time clock. This breaks the */ + /* test code which assumes which assumes the application will do it. */ + { + rtems_time_of_day now; + + /* External Prototypes */ + extern void init_rtc(void); /* defined in 'rtc.c' */ + extern long rtc_read(rtems_time_of_day *); /* defined in 'rtc.c' */ + +#ifdef BSP_DEBUG + printk("Loading clock from on-board real-time clock.\n"); +#endif + + init_rtc(); + if (rtc_read(&now) >= 0) + rtems_clock_set(&now); + } +#endif + + Clock_driver_ticks = 0; + + Clock_isrs = + Clock_initial_isr_value = + BSP_Configuration.microseconds_per_tick / 1000; /* ticks per clock_isr */ + + /* + * configure the counter timer ( should be based on microsecs/tick ) + * NB. The divisor(Clock_isrs) resolves the is the same number that appears in confdefs.h + * when setting the microseconds_per_tick value. + */ + ClockOff ( &clockIrqData ); + + timer_counter_init_value = BSP_Configuration.microseconds_per_tick / Clock_isrs; + clock_lsb = (unsigned char)timer_counter_init_value; + clock_msb = timer_counter_init_value >> 8; + + outport_byte (TIMER_MODE, TIMER_SEL0|TIMER_16BIT|TIMER_RATEGEN); + outport_byte (TIMER_CNTR0, clock_lsb ); /* load LSB first */ + outport_byte (TIMER_CNTR0, clock_msb ); /* then MSB */ + + if (!BSP_install_rtems_irq_handler (&clockIrqData)) { + printk("Unable to initialize system clock\n"); + rtems_fatal_error_occurred(1); + } + + /* + * 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(); + } + else if (args->command == rtems_build_name('N', 'E', 'W', ' ')) + { + if (!BSP_install_rtems_irq_handler (&clockIrqData)) { + printk("Error installing clock interrupt handler!\n"); + rtems_fatal_error_occurred(1); + } +#ifdef BSP_DEBUG + else + printk("Clock installed AGAIN\n"); +#endif + } + +done: + return RTEMS_SUCCESSFUL; +} + +void Clock_exit() +{ + ClockOff(&clockIrqData); + BSP_remove_rtems_irq_handler (&clockIrqData); +} diff --git a/c/src/lib/libbsp/i386/ts_386ex/clock/rtc.c b/c/src/lib/libbsp/i386/ts_386ex/clock/rtc.c new file mode 100644 index 0000000000..14a20e5f3f --- /dev/null +++ b/c/src/lib/libbsp/i386/ts_386ex/clock/rtc.c @@ -0,0 +1,226 @@ +/*-------------------------------------------------------------------------+ +| rtc.c v1.1 - PC386 BSP - 1997/08/07 ++--------------------------------------------------------------------------+ +| This file contains the real time clock manipulation package for the +| PC386 board. ++--------------------------------------------------------------------------+ +| (C) Copyright 1997 - +| - NavIST Group - Real-Time Distributed Systems and Industrial Automation +| +| http://pandora.ist.utl.pt +| +| Instituto Superior Tecnico * Lisboa * PORTUGAL ++--------------------------------------------------------------------------+ +| Disclaimer: +| +| This file is provided "AS IS" without warranty of any kind, either +| expressed or implied. ++--------------------------------------------------------------------------+ +| This code is based on: +| rtc.c,v 1.4 1995/12/19 20:07:15 joel Exp - go32 BSP +| With the following copyright notice: +| ************************************************************************** +| * COPYRIGHT (c) 1989-1998. +| * On-Line Applications Research Corporation (OAR). +| * Copyright assigned to U.S. Government, 1994. +| * +| * The license and distribution terms for this file may be +| * found in found in the file LICENSE in this distribution or at +| * http://www.OARcorp.com/rtems/license.html. +| ************************************************************************** +| +| $Id$ ++--------------------------------------------------------------------------*/ + + +#include + +#include + +/*-------------------------------------------------------------------------+ +| Constants ++--------------------------------------------------------------------------*/ +#define IO_RTC 0x70 /* RTC */ + +#define RTC_SEC 0x00 /* seconds */ +#define RTC_SECALRM 0x01 /* seconds alarm */ +#define RTC_MIN 0x02 /* minutes */ +#define RTC_MINALRM 0x03 /* minutes alarm */ +#define RTC_HRS 0x04 /* hours */ +#define RTC_HRSALRM 0x05 /* hours alarm */ +#define RTC_WDAY 0x06 /* week day */ +#define RTC_DAY 0x07 /* day of month */ +#define RTC_MONTH 0x08 /* month of year */ +#define RTC_YEAR 0x09 /* month of year */ +#define RTC_STATUSA 0x0a /* status register A */ +#define RTCSA_TUP 0x80 /* time update, don't look now */ + +#define RTC_STATUSB 0x0b /* status register B */ + +#define RTC_INTR 0x0c /* status register C (R) interrupt source */ +#define RTCIR_UPDATE 0x10 /* update intr */ +#define RTCIR_ALARM 0x20 /* alarm intr */ +#define RTCIR_PERIOD 0x40 /* periodic intr */ +#define RTCIR_INT 0x80 /* interrupt output signal */ + +#define RTC_STATUSD 0x0d /* status register D (R) Lost Power */ +#define RTCSD_PWR 0x80 /* clock lost power */ + +#define RTC_DIAG 0x0e /* status register E - bios diagnostic */ +#define RTCDG_BITS "\020\010clock_battery\007ROM_cksum\006config_unit\005memory_size\004fixed_disk\003invalid_time" + +#define RTC_CENTURY 0x32 /* current century - increment in Dec99 */ + + +/*-------------------------------------------------------------------------+ +| Auxiliary Functions ++--------------------------------------------------------------------------*/ +/*-------------------------------------------------------------------------+ +| Function: bcd +| Description: Convert 2 digit number to its BCD representation. +| Global Variables: None. +| Arguments: i - Number to convert. +| Returns: BCD representation of number. ++--------------------------------------------------------------------------*/ +static inline rtems_unsigned8 +bcd(rtems_unsigned8 i) +{ + return ((i / 16) * 10 + (i % 16)); +} /* bcd */ + +#define QUICK_READ /* Quick read of the RTC: don't return number of seconds. */ + +#ifndef QUICK_READ + +#define SECS_PER_DAY (24 * 60 * 60) +#define SECS_PER_REG_YEAR (365 * SECS_PER_DAY) + +/*-------------------------------------------------------------------------+ +| Function: ytos +| Description: Convert years to seconds (since 1970). +| Global Variables: None. +| Arguments: y - year to convert (1970 <= y <= 2100). +| Returns: number of seconds since 1970. ++--------------------------------------------------------------------------*/ +static inline rtems_unsigned32 +ytos(rtems_unsigned16 y) +{ /* v NUM LEAP YEARS v */ + return ((y - 1970) * SECS_PER_REG_YEAR + (y - 1970 + 1) / 4 * SECS_PER_DAY); +} /* ytos */ + + +/*-------------------------------------------------------------------------+ +| Function: mtos +| Description: Convert months to seconds since January. +| Global Variables: None. +| Arguments: m - month to convert, leap - is this a month of a leap year. +| Returns: number of seconds since January. ++--------------------------------------------------------------------------*/ +static inline rtems_unsigned32 +mtos(rtems_unsigned8 m, rtems_boolean leap) +{ + static rtems_unsigned16 daysMonth[] = { 0, 0, 31, 59, 90, 120, 151, 181, + 212, 243, 273, 304, 334, 365 }; + /* Days since beginning of year until beginning of month. */ + + return ((daysMonth[m] + (leap ? 1 : 0)) * SECS_PER_DAY); +} /* mtos */ + +#endif /* QUICK_READ */ + +/*-------------------------------------------------------------------------+ +| Function: rtcin +| Description: Perform action on RTC and return its result. +| Global Variables: None. +| Arguments: what - what to write to RTC port (what to do). +| Returns: result received from RTC port after action performed. ++--------------------------------------------------------------------------*/ +static inline rtems_unsigned8 +rtcin(rtems_unsigned8 what) +{ + rtems_unsigned8 r; + + outport_byte(IO_RTC, what); + inport_byte (IO_RTC+1, r); + return r; +} /* rtcin */ + + +/*-------------------------------------------------------------------------+ +| Functions ++--------------------------------------------------------------------------*/ +/*-------------------------------------------------------------------------+ +| Function: init_rtc +| Description: Initialize real-time clock (RTC). +| Global Variables: None. +| Arguments: None. +| Returns: Nothing. ++--------------------------------------------------------------------------*/ +void +init_rtc(void) +{ + rtems_unsigned8 s; + + /* initialize brain-dead battery powered clock */ + outport_byte(IO_RTC, RTC_STATUSA); + outport_byte(IO_RTC+1, 0x26); + outport_byte(IO_RTC, RTC_STATUSB); + outport_byte(IO_RTC+1, 2); + + outport_byte(IO_RTC, RTC_DIAG); + inport_byte (IO_RTC+1, s); + if (s) + printk("RTC BIOS diagnostic error %b\n", s); + + /* FIXME: This was last line's original version. How was it supposed to work? + printf("RTC BIOS diagnostic error %b\n", s, RTCDG_BITS); */ +} /* init_rtc */ + + +/*-------------------------------------------------------------------------+ +| Function: rtc_read +| Description: Read present time from RTC and return it. +| Global Variables: None. +| Arguments: tod - to return present time in 'rtems_time_of_day' format. +| Returns: number of seconds from 1970/01/01 corresponding to 'tod'. ++--------------------------------------------------------------------------*/ +long int +rtc_read(rtems_time_of_day *tod) +{ + rtems_unsigned8 sa; + rtems_unsigned32 sec = 0; + + memset(tod, 0, sizeof *tod); /* zero tod structure */ + + /* do we have a realtime clock present? (otherwise we loop below) */ + sa = rtcin(RTC_STATUSA); + if (sa == 0xff || sa == 0) + return -1; + + /* ready for a read? */ + while ((sa&RTCSA_TUP) == RTCSA_TUP) + sa = rtcin(RTC_STATUSA); + + tod->year = bcd(rtcin(RTC_YEAR)) + 1900; /* year */ + if (tod->year < 1970) tod->year += 100; + tod->month = bcd(rtcin(RTC_MONTH)); /* month */ + tod->day = bcd(rtcin(RTC_DAY)); /* day */ + (void) bcd(rtcin(RTC_WDAY)); /* weekday */ + tod->hour = bcd(rtcin(RTC_HRS)); /* hour */ + tod->minute = bcd(rtcin(RTC_MIN)); /* minutes */ + tod->second = bcd(rtcin(RTC_SEC)); /* seconds */ + tod->ticks = 0; + +#ifndef QUICK_READ /* Quick read of the RTC: don't return number of seconds. */ + sec = ytos(tod->year); + sec += mtos(tod->month, (tod->year % 4) == 0); + sec += tod->day * SECS_PER_DAY; + sec += tod->hour * 60 * 60; /* hour */ + sec += tod->minute * 60; /* minutes */ + sec += tod->second; /* seconds */ +#endif /* QUICK_READ */ + + return (long int)sec; +} /* rtc_read */ + + diff --git a/c/src/lib/libbsp/i386/ts_386ex/console/Makefile.in b/c/src/lib/libbsp/i386/ts_386ex/console/Makefile.in new file mode 100644 index 0000000000..872b966f52 --- /dev/null +++ b/c/src/lib/libbsp/i386/ts_386ex/console/Makefile.in @@ -0,0 +1,74 @@ +# +# $Id$ +# + +@SET_MAKE@ +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +top_builddir = ../../../../../../.. +subdir = c/src/lib/libbsp/i386/ts_386ex/console + +INSTALL = @INSTALL@ + +RTEMS_ROOT = $(top_srcdir)/@RTEMS_TOPdir@ +PROJECT_ROOT = @PROJECT_ROOT@ + +VPATH = @srcdir@ + +PGM=${ARCH}/console.rel + +IMPORT_SRC=$(srcdir)/../../shared/io/printk.c + +# C source names, if any, go here -- minus the .c +C_PIECES=console printk +C_FILES=$(C_PIECES:%=%.c) +C_O_FILES=$(C_PIECES:%=${ARCH}/%.o) + +H_FILES= + +# Assembly source names, if any, go here -- minus the .S +S_PIECES= +S_FILES=$(S_PIECES:%=%.S) +S_O_FILES=$(S_FILES:%.S=${ARCH}/%.o) + +SRCS=$(C_FILES) $(CC_FILES) $(H_FILES) $(S_FILES) +OBJS=$(C_O_FILES) $(CC_O_FILES) $(S_O_FILES) + +include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg +include $(RTEMS_ROOT)/make/leaf.cfg + +# +# (OPTIONAL) Add local stuff here using += +# + +DEFINES += +CFLAGS += + +LD_PATHS += +LD_LIBS += +LDFLAGS += + +# +# Add your list of files to delete here. The config files +# already know how to delete some stuff, so you may want +# to just run 'make clean' first to see what gets missed. +# 'make clobber' already includes 'make clean' +# + +CLEAN_ADDITIONS += +CLOBBER_ADDITIONS += + +preinstall: + ${CP} ${IMPORT_SRC} . + +${PGM}: ${SRCS} ${OBJS} + $(make-rel) + +all: ${ARCH} preinstall $(SRCS) $(PGM) + +# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile +install: all + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status diff --git a/c/src/lib/libbsp/i386/ts_386ex/console/console.c b/c/src/lib/libbsp/i386/ts_386ex/console/console.c new file mode 100644 index 0000000000..2db6b52bd0 --- /dev/null +++ b/c/src/lib/libbsp/i386/ts_386ex/console/console.c @@ -0,0 +1,399 @@ +/*-------------------------------------------------------------------------+ +| console.c v1.1 - i386ex BSP - 1997/08/07 ++--------------------------------------------------------------------------+ +| This file contains the i386ex console I/O package. It is just a termios +| wrapper. ++--------------------------------------------------------------------------+ +| (C) Copyright 1997 - +| - NavIST Group - Real-Time Distributed Systems and Industrial Automation +| +| http://pandora.ist.utl.pt +| +| Instituto Superior Tecnico * Lisboa * PORTUGAL ++--------------------------------------------------------------------------+ +| Disclaimer: +| +| This file is provided "AS IS" without warranty of any kind, either +| expressed or implied. ++--------------------------------------------------------------------------+ +| This code is based on: +| console.c,v 1.4 1995/12/19 20:07:23 joel Exp - go32 BSP +| console.c,v 1.15 pc386 BSP +| With the following copyright notice: +| ************************************************************************** +| * COPYRIGHT (c) 1989-1998. +| * On-Line Applications Research Corporation (OAR). +| * Copyright assigned to U.S. Government, 1994. +| * +| * The license and distribution terms for this file may be +| * found in found in the file LICENSE in this distribution or at +| * http://www.OARcorp.com/rtems/license.html. +| ************************************************************************** +| +| $Id$ ++--------------------------------------------------------------------------*/ + +#include +#include +#include + +/* workaround for gcc development tools */ +#undef __assert +void __assert (const char *file, int line, const char *msg); + +#include +#include +#include +#include +#include +#include + +/* + * Possible value for console input/output : + * BSP_UART_COM1 + * BSP_UART_COM2 + * BSP_CONSOLE_PORT_CONSOLE is not valid in this BSP. + * All references to either keyboard or video handling have been removed. + */ + +int BSPConsolePort = BSP_UART_COM2; +int BSPBaseBaud = 115200; +int BSP_poll_read(int); + +extern BSP_polling_getchar_function_type BSP_poll_char; + +static int conSetAttr(int minor, const struct termios *); +static void isr_on(const rtems_irq_connect_data *); +static void isr_off(const rtems_irq_connect_data *); +static int isr_is_on(const rtems_irq_connect_data *); + +/* + * Change references to com2 if required. + */ + +static rtems_irq_connect_data console_isr_data = +{ BSP_UART_COM2_IRQ, + BSP_uart_termios_isr_com2, + isr_on, + isr_off, + isr_is_on}; + +static void +isr_on(const rtems_irq_connect_data *unused) +{ + return; +} + +static void +isr_off(const rtems_irq_connect_data *unused) +{ + return; +} + +static int +isr_is_on(const rtems_irq_connect_data *irq) +{ + return BSP_irq_enabled_at_i8259s(irq->name); +} + +void console_reserve_resources(rtems_configuration_table *conf) +{ + rtems_termios_reserve_resources(conf, 1); + return; +} + +void __assert (const char *file, int line, const char *msg) +{ + static char exit_msg[] = "EXECUTIVE SHUTDOWN! Any key to reboot..."; + unsigned char ch; + + /* + * Note we cannot call exit or printf from here, + * assert can fail inside ISR too + */ + + /* + * Close console + */ + close(2); + close(1); + close(0); + + printk("\nassert failed: %s: ", file); + printk("%d: ", line); + printk("%s\n\n", msg); + printk(exit_msg); + ch = BSP_poll_char(); + printk("\nShould jump to reset now!\n"); +} + + +/*-------------------------------------------------------------------------+ +| Console device driver INITIALIZE entry point. ++--------------------------------------------------------------------------+ +| Initilizes the I/O console (keyboard + VGA display) driver. ++--------------------------------------------------------------------------*/ +rtems_device_driver +console_initialize(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) +{ + rtems_status_code status; + + /* + * Set up TERMIOS + */ + rtems_termios_initialize (); + + /* + * Do device-specific initialization + */ + + /* 115200-8-N-1, without hardware flow control */ + BSP_uart_init(BSPConsolePort, 115200, 0); + + /* Set interrupt handler */ + if(BSPConsolePort == BSP_UART_COM1) + { + console_isr_data.name = BSP_UART_COM1_IRQ; + console_isr_data.hdl = BSP_uart_termios_isr_com1; + + } + else + { + assert(BSPConsolePort == BSP_UART_COM2); + console_isr_data.name = BSP_UART_COM2_IRQ; + console_isr_data.hdl = BSP_uart_termios_isr_com2; + } + + status = BSP_install_rtems_irq_handler(&console_isr_data); + + if (!status){ + printk("Error installing serial console interrupt handler!\n"); + rtems_fatal_error_occurred(status); + } + /* + * Register the device + */ + status = rtems_io_register_name ("/dev/console", major, 0); + if (status != RTEMS_SUCCESSFUL) + { + printk("Error registering console device!\n"); + rtems_fatal_error_occurred (status); + } + + if(BSPConsolePort == BSP_UART_COM1) + { + printk("Initialized console on port COM1 115200-8-N-1\n\n"); + } + else + { + printk("Initialized console on port COM2 115200-8-N-1\n\n"); + } + + return RTEMS_SUCCESSFUL; +} /* console_initialize */ + + +static int console_open_count = 0; + +static int console_last_close(int major, int minor, void *arg) +{ + BSP_remove_rtems_irq_handler (&console_isr_data); + + return 0; +} + +/*-------------------------------------------------------------------------+ +| Console device driver OPEN entry point ++--------------------------------------------------------------------------*/ +rtems_device_driver +console_open(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) +{ + rtems_status_code status; + static rtems_termios_callbacks cb = + { + NULL, /* firstOpen */ + console_last_close, /* lastClose */ + NULL, /* poll read */ + BSP_uart_termios_write_com2, /* write */ + conSetAttr, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + 1 /* outputUsesInterrupts */ + }; + + if(BSPConsolePort == BSP_UART_COM2) + { + cb.write = BSP_uart_termios_write_com2; + } + + status = rtems_termios_open (major, minor, arg, &cb); + + if(status != RTEMS_SUCCESSFUL) + { + printk("Error openning console device\n"); + return status; + } + + /* + * Pass data area info down to driver + */ + BSP_uart_termios_set(BSPConsolePort, + ((rtems_libio_open_close_args_t *)arg)->iop->data1); + + /* Enable interrupts on channel */ + BSP_uart_intr_ctrl(BSPConsolePort, BSP_UART_INTR_CTRL_TERMIOS); + + return RTEMS_SUCCESSFUL; +} + +/*-------------------------------------------------------------------------+ +| Console device driver CLOSE entry point ++--------------------------------------------------------------------------*/ +rtems_device_driver +console_close(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) +{ + + return (rtems_termios_close (arg)); + +} /* console_close */ + + +/*-------------------------------------------------------------------------+ +| Console device driver READ entry point. ++--------------------------------------------------------------------------+ +| Read characters from the I/O console. We only have stdin. ++--------------------------------------------------------------------------*/ +rtems_device_driver +console_read(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) +{ + rtems_status_code sc; + + sc = rtems_termios_read (arg); + + if ( sc != RTEMS_SUCCESSFUL ) + printk("console_read: fails %s\n",rtems_status_text(sc)); + + return sc; + +} /* console_read */ + + +/*-------------------------------------------------------------------------+ +| Console device driver WRITE entry point. ++--------------------------------------------------------------------------+ +| Write characters to the I/O console. Stderr and stdout are the same. ++--------------------------------------------------------------------------*/ +rtems_device_driver +console_write(rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg) +{ + return rtems_termios_write (arg); + +} /* console_write */ + + + +/* + * Handle ioctl request. + */ +rtems_device_driver +console_control(rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return rtems_termios_ioctl (arg); +} + +static int +conSetAttr(int minor, const struct termios *t) +{ + int baud; + + switch (t->c_cflag & CBAUD) + { + case B50: + baud = 50; + break; + case B75: + baud = 75; + break; + case B110: + baud = 110; + break; + case B134: + baud = 134; + break; + case B150: + baud = 150; + break; + case B200: + baud = 200; + break; + case B300: + baud = 300; + break; + case B600: + baud = 600; + break; + case B1200: + baud = 1200; + break; + case B1800: + baud = 1800; + break; + case B2400: + baud = 2400; + break; + case B4800: + baud = 4800; + break; + case B9600: + baud = 9600; + break; + case B19200: + baud = 19200; + break; + case B38400: + baud = 38400; + break; + case B57600: + baud = 57600; + break; + case B115200: + baud = 115200; + break; + default: + baud = 0; + rtems_fatal_error_occurred (RTEMS_INTERNAL_ERROR); + return 0; + } + + BSP_uart_set_baud(BSPConsolePort, baud); + + return 0; +} + +/* + * BSP initialization + */ + +BSP_output_char_function_type BSP_output_char = + (BSP_output_char_function_type) BSP_output_char_via_serial; + +BSP_polling_getchar_function_type BSP_poll_char = + (BSP_polling_getchar_function_type) BSP_poll_char_via_serial; + +int BSP_poll_read(int ttyMinor){ + + return BSP_poll_char_via_serial(); +} diff --git a/c/src/lib/libbsp/i386/ts_386ex/include/Makefile.in b/c/src/lib/libbsp/i386/ts_386ex/include/Makefile.in new file mode 100644 index 0000000000..49be342e7a --- /dev/null +++ b/c/src/lib/libbsp/i386/ts_386ex/include/Makefile.in @@ -0,0 +1,50 @@ +# +# $Id$ +# + +@SET_MAKE@ +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +top_builddir = ../../../../../../.. +subdir = c/src/lib/libbsp/i386/ts_386ex/include + +INSTALL = @INSTALL@ + +RTEMS_ROOT = $(top_srcdir)/@RTEMS_TOPdir@ +PROJECT_ROOT = @PROJECT_ROOT@ + +VPATH = @srcdir@ + +# We only install wd80x3.h if HAS_NETWORKING was defined +NE2000_yes_V = $(srcdir)/wd80x3.h +NE2000 = $(NE2000_$(HAS_NETWORKING)_V) + +H_FILES = $(srcdir)/bsp.h $(srcdir)/coverhd.h $(NE2000) + +# +# Equate files are for including from assembly preprocessed by +# gm4 or gasp. No examples are provided except for those for +# other CPUs. The best way to generate them would be to +# provide a program which generates the constants used based +# on the C equivalents. +# + +EQ_FILES = + +SRCS=$(H_FILES) $(EQ_FILES) + +include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg +include $(RTEMS_ROOT)/make/leaf.cfg + +CLEAN_ADDITIONS += +CLOBBER_ADDITIONS += + +all: $(SRCS) + $(INSTALL_CHANGE) -m 444 $(H_FILES) $(PROJECT_INCLUDE) + $(INSTALL_CHANGE) -m 444 $(EQ_FILES) $(PROJECT_INCLUDE) + +install: all + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status diff --git a/c/src/lib/libbsp/i386/ts_386ex/include/bsp.h b/c/src/lib/libbsp/i386/ts_386ex/include/bsp.h new file mode 100644 index 0000000000..f19341c853 --- /dev/null +++ b/c/src/lib/libbsp/i386/ts_386ex/include/bsp.h @@ -0,0 +1,186 @@ +/* + * This include file definitions related to an Intel i386ex board. + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * 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 __TS386_h +#define __TS386_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include +#include + +/* + * Network driver configuration + */ + +struct rtems_bsdnet_ifconfig; +extern int rtems_ne_driver_attach (struct rtems_bsdnet_ifconfig *config); + +extern void Wait_X_ms (unsigned); + +#define RTEMS_BSP_NETWORK_DRIVER_NAME "ne1" +#define RTEMS_BSP_NETWORK_DRIVER_ATTACH rtems_ne_driver_attach + +#define NE2000_BYTE_TRANSFERS + +/* + * Constants relating to the 8254 (or 8253) programmable interval timers. + */ + +#define TIMER_CONFIG 0xF834 +#define IO_TIMER1 0xF040 + + /* Port address of the control port and timer channels */ + +#define TIMER_CNTR0 (IO_TIMER1 + 0) /* timer 0 counter port */ +#define TIMER_CNTR1 (IO_TIMER1 + 1) /* timer 1 counter port */ +#define TIMER_CNTR2 (IO_TIMER1 + 2) /* timer 2 counter port */ +#define TIMER_MODE (IO_TIMER1 + 3) /* timer mode port */ +#define TIMER_SEL0 0x00 /* select counter 0 */ +#define TIMER_SEL1 0x40 /* select counter 1 */ +#define TIMER_SEL2 0x80 /* select counter 2 */ +#define TIMER_INTTC 0x00 /* mode 0, intr on terminal cnt */ +#define TIMER_ONESHOT 0x02 /* mode 1, one shot */ +#define TIMER_RATEGEN 0x04 /* mode 2, rate generator */ +#define TIMER_SQWAVE 0x06 /* mode 3, square wave */ +#define TIMER_SWSTROBE 0x08 /* mode 4, s/w triggered strobe */ +#define TIMER_HWSTROBE 0x0a /* mode 5, h/w triggered strobe */ +#define TIMER_LATCH 0x00 /* latch counter for reading */ +#define TIMER_LSB 0x10 /* r/w counter LSB */ +#define TIMER_MSB 0x20 /* r/w counter MSB */ +#define TIMER_16BIT 0x30 /* r/w counter 16 bits, LSB first */ +#define TIMER_BCD 0x01 /* count in BCD */ + +/* + * 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 + * + * NOTE: Use a software interrupt for the i386. + */ + +#define MUST_WAIT_FOR_INTERRUTPT 0 + + +#define Install_tm27_vector(handler) \ +{ \ + rtems_isr_entry dummy; \ + rtems_interrupt_catch(handler, 0x90, &dummy); \ +} +#define Cause_tm27_intr() asm volatile( "int $0x90" : : ); + +#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 ) \ + { \ + rtems_unsigned32 _counter; \ + \ + _counter = (_microseconds); \ + \ + asm volatile ( "0: nop;" \ + " mov %0,%0 ;" \ + " loop 0b" : "=c" (_counter) \ + : "0" (_counter) \ + ); \ + \ + } + +/* Constants */ + +#define RAM_START 0 + +/* replaced the earlier EI kludge of 0xfffff */ + +#define RAM_END 0x200000 + +/* I/O addressing */ + +/* + *#define Is_tx_ready( _status ) ( (_status) & 0x20 ) + */ +/* dec 20. try the TE instead of TBE as the check */ + +#define Is_tx_ready( _status ) ( (_status) & 0x40 ) + + +#define Is_rx_ready( _status ) ( (_status) & 0x01 ) + +/* Structures */ + +#ifdef F386_INIT +#undef BSP_EXTERN +#define BSP_EXTERN +#else +#undef BSP_EXTERN +#define BSP_EXTERN extern +#endif + +/* + * Device Driver Table Entries + */ + +/* + * NOTE: Use the standard Console driver entry + */ + +/* + * NOTE: Use the standard Clock driver entry + */ + +/* miscellaneous stuff assumed to exist */ + +extern rtems_configuration_table BSP_Configuration; + +#define IDT_SIZE 256 +#define GDT_SIZE 3 + +extern interrupt_gate_descriptor Interrupt_descriptor_table[IDT_SIZE]; +extern segment_descriptors Global_descriptor_table [GDT_SIZE]; + +BSP_EXTERN unsigned short Idt[3]; /* Interrupt Descriptor Table Address */ +BSP_EXTERN unsigned short Gdt[3]; /* Global Descriptor Table Address */ +BSP_EXTERN unsigned int Idt_base; +BSP_EXTERN unsigned int Gdt_base; + +/* routines */ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/c/src/lib/libbsp/i386/ts_386ex/include/coverhd.h b/c/src/lib/libbsp/i386/ts_386ex/include/coverhd.h new file mode 100644 index 0000000000..de5e7aa742 --- /dev/null +++ b/c/src/lib/libbsp/i386/ts_386ex/include/coverhd.h @@ -0,0 +1,104 @@ +/* coverhd.h + * + * This include file has defines to represent the overhead associated + * with calling a particular directive from C on this target. + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * 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 __COVERHD_h +#define __COVERHD_h + +#ifdef __cplusplus +extern "C" { +#endif + +#define CALLING_OVERHEAD_INITIALIZE_EXECUTIVE 3 +#define CALLING_OVERHEAD_SHUTDOWN_EXECUTIVE 3 +#define CALLING_OVERHEAD_TASK_CREATE 4 +#define CALLING_OVERHEAD_TASK_IDENT 4 +#define CALLING_OVERHEAD_TASK_START 4 +#define CALLING_OVERHEAD_TASK_RESTART 3 +#define CALLING_OVERHEAD_TASK_DELETE 3 +#define CALLING_OVERHEAD_TASK_SUSPEND 3 +#define CALLING_OVERHEAD_TASK_RESUME 3 +#define CALLING_OVERHEAD_TASK_SET_PRIORITY 4 +#define CALLING_OVERHEAD_TASK_MODE 4 +#define CALLING_OVERHEAD_TASK_GET_NOTE 4 +#define CALLING_OVERHEAD_TASK_SET_NOTE 4 +#define CALLING_OVERHEAD_TASK_WAKE_WHEN 7 +#define CALLING_OVERHEAD_TASK_WAKE_AFTER 3 +#define CALLING_OVERHEAD_INTERRUPT_CATCH 4 +#define CALLING_OVERHEAD_CLOCK_GET 7 +#define CALLING_OVERHEAD_CLOCK_SET 7 +#define CALLING_OVERHEAD_CLOCK_TICK 2 + +#define CALLING_OVERHEAD_TIMER_CREATE 3 +#define CALLING_OVERHEAD_TIMER_IDENT 3 +#define CALLING_OVERHEAD_TIMER_DELETE 3 +#define CALLING_OVERHEAD_TIMER_FIRE_AFTER 4 +#define CALLING_OVERHEAD_TIMER_FIRE_WHEN 8 +#define CALLING_OVERHEAD_TIMER_RESET 3 +#define CALLING_OVERHEAD_TIMER_CANCEL 3 +#define CALLING_OVERHEAD_SEMAPHORE_CREATE 4 +#define CALLING_OVERHEAD_SEMAPHORE_DELETE 3 +#define CALLING_OVERHEAD_SEMAPHORE_IDENT 4 +#define CALLING_OVERHEAD_SEMAPHORE_OBTAIN 4 +#define CALLING_OVERHEAD_SEMAPHORE_RELEASE 3 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_CREATE 4 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_IDENT 4 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_DELETE 3 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_SEND 3 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_URGENT 3 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_BROADCAST 4 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_RECEIVE 4 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_FLUSH 3 + +#define CALLING_OVERHEAD_EVENT_SEND 4 +#define CALLING_OVERHEAD_EVENT_RECEIVE 4 +#define CALLING_OVERHEAD_SIGNAL_CATCH 3 +#define CALLING_OVERHEAD_SIGNAL_SEND 3 +#define CALLING_OVERHEAD_PARTITION_CREATE 4 +#define CALLING_OVERHEAD_PARTITION_IDENT 4 +#define CALLING_OVERHEAD_PARTITION_DELETE 3 +#define CALLING_OVERHEAD_PARTITION_GET_BUFFER 4 +#define CALLING_OVERHEAD_PARTITION_RETURN_BUFFER 4 +#define CALLING_OVERHEAD_REGION_CREATE 4 +#define CALLING_OVERHEAD_REGION_IDENT 3 +#define CALLING_OVERHEAD_REGION_DELETE 3 +#define CALLING_OVERHEAD_REGION_GET_SEGMENT 4 +#define CALLING_OVERHEAD_REGION_RETURN_SEGMENT 4 +#define CALLING_OVERHEAD_PORT_CREATE 4 +#define CALLING_OVERHEAD_PORT_IDENT 3 +#define CALLING_OVERHEAD_PORT_DELETE 3 +#define CALLING_OVERHEAD_PORT_EXTERNAL_TO_INTERNAL 4 +#define CALLING_OVERHEAD_PORT_INTERNAL_TO_EXTERNAL 4 + +#define CALLING_OVERHEAD_IO_INITIALIZE 4 +#define CALLING_OVERHEAD_IO_OPEN 4 +#define CALLING_OVERHEAD_IO_CLOSE 4 +#define CALLING_OVERHEAD_IO_READ 4 +#define CALLING_OVERHEAD_IO_WRITE 4 +#define CALLING_OVERHEAD_IO_CONTROL 4 +#define CALLING_OVERHEAD_FATAL_ERROR_OCCURRED 3 +#define CALLING_OVERHEAD_RATE_MONOTONIC_CREATE 3 +#define CALLING_OVERHEAD_RATE_MONOTONIC_IDENT 3 +#define CALLING_OVERHEAD_RATE_MONOTONIC_DELETE 3 +#define CALLING_OVERHEAD_RATE_MONOTONIC_CANCEL 3 +#define CALLING_OVERHEAD_RATE_MONOTONIC_PERIOD 3 +#define CALLING_OVERHEAD_MULTIPROCESSING_ANNOUNCE 2 + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/c/src/lib/libbsp/i386/ts_386ex/include/wd80x3.h b/c/src/lib/libbsp/i386/ts_386ex/include/wd80x3.h new file mode 100644 index 0000000000..4bad00993c --- /dev/null +++ b/c/src/lib/libbsp/i386/ts_386ex/include/wd80x3.h @@ -0,0 +1,123 @@ + +/* Register descriptions */ +/* Controller DP8390. */ + +#define DATAPORT 0x10 /* Port Window. */ +#define RESET 0x1f /* Issue a read for reset */ +#define W83CREG 0x00 /* I/O port definition */ +#define ADDROM 0x08 + +/* page 0 read or read/write registers */ + +#define CMDR 0x00+RO +#define CLDA0 0x01+RO /* current local dma addr 0 for read */ +#define CLDA1 0x02+RO /* current local dma addr 1 for read */ +#define BNRY 0x03+RO /* boundary reg for rd and wr */ +#define TSR 0x04+RO /* tx status reg for rd */ +#define NCR 0x05+RO /* number of collision reg for rd */ +#define FIFO 0x06+RO /* FIFO for rd */ +#define ISR 0x07+RO /* interrupt status reg for rd and wr */ +#define CRDA0 0x08+RO /* current remote dma address 0 for rd */ +#define CRDA1 0x09+RO /* current remote dma address 1 for rd */ +#define RSR 0x0C+RO /* rx status reg for rd */ +#define CNTR0 0x0D+RO /* tally cnt 0 for frm alg err for rd */ +#define CNTR1 RO+0x0E /* tally cnt 1 for crc err for rd */ +#define CNTR2 0x0F+RO /* tally cnt 2 for missed pkt for rd */ + +/* page 0 write registers */ + +#define PSTART 0x01+RO /* page start register */ +#define PSTOP 0x02+RO /* page stop register */ +#define TPSR 0x04+RO /* tx start page start reg */ +#define TBCR0 0x05+RO /* tx byte count 0 reg */ +#define TBCR1 0x06+RO /* tx byte count 1 reg */ +#define RSAR0 0x08+RO /* remote start address reg 0 */ +#define RSAR1 0x09+RO /* remote start address reg 1 */ +#define RBCR0 0x0A+RO /* remote byte count reg 0 */ +#define RBCR1 0x0B+RO /* remote byte count reg 1 */ +#define RCR 0x0C+RO /* rx configuration reg */ +#define TCR 0x0D+RO /* tx configuration reg */ +#define DCR RO+0x0E /* data configuration reg */ +#define IMR 0x0F+RO /* interrupt mask reg */ + +/* page 1 registers */ + +#define PAR 0x01+RO /* physical addr reg base for rd and wr */ +#define CURR 0x07+RO /* current page reg for rd and wr */ +#define MAR 0x08+RO /* multicast addr reg base fro rd and WR */ +#define MARsize 8 /* size of multicast addr space */ + +/*-----W83CREG command bits-----*/ +#define MSK_RESET 0x80 /* W83CREG masks */ +#define MSK_ENASH 0x40 +#define MSK_DECOD 0x3F /* memory decode bits, corresponding */ + /* to SA 18-13. SA 19 assumed to be 1 */ + +/*-----CMDR command bits-----*/ +#define MSK_STP 0x01 /* stop the chip */ +#define MSK_STA 0x02 /* start the chip */ +#define MSK_TXP 0x04 /* initial txing of a frm */ +#define MSK_RRE 0x08 /* remote read */ +#define MSK_RWR 0x10 /* remote write */ +#define MSK_RD2 0x20 /* no DMA used */ +#define MSK_PG0 0x00 /* select register page 0 */ +#define MSK_PG1 0x40 /* select register page 1 */ +#define MSK_PG2 0x80 /* select register page 2 */ + +/*-----ISR and TSR status bits-----*/ +#define MSK_PRX 0x01 /* rx with no error */ +#define MSK_PTX 0x02 /* tx with no error */ +#define MSK_RXE 0x04 /* rx with error */ +#define MSK_TXE 0x08 /* tx with error */ +#define MSK_OVW 0x10 /* overwrite warning */ +#define MSK_CNT 0x20 /* MSB of one of the tally counters is set */ +#define MSK_RDC 0x40 /* remote dma completed */ +#define MSK_RST 0x80 /* reset state indicator */ + +/*-----DCR command bits-----*/ +#define MSK_WTS 0x01 /* word transfer mode selection */ +#define MSK_BOS 0x02 /* byte order selection */ +#define MSK_LAS 0x04 /* long addr selection */ +#define MSK_BMS 0x08 /* burst mode selection */ +#define MSK_ARM 0x10 /* autoinitialize remote */ +#define MSK_FT00 0x00 /* burst lrngth selection */ +#define MSK_FT01 0x20 /* burst lrngth selection */ +#define MSK_FT10 0x40 /* burst lrngth selection */ +#define MSK_FT11 0x60 /* burst lrngth selection */ + +/*-----RCR command bits-----*/ +#define MSK_SEP 0x01 /* save error pkts */ +#define MSK_AR 0x02 /* accept runt pkt */ +#define MSK_AB 0x04 /* 8390 RCR */ +#define MSK_AM 0x08 /* accept multicast */ +#define MSK_PRO 0x10 /* accept all pkt with physical adr */ +#define MSK_MON 0x20 /* monitor mode */ + +/*-----TCR command bits-----*/ +#define MSK_CRC 0x01 /* inhibit CRC, do not append crc */ +#define MSK_LOOP 0x02 /* set loopback mode */ +#define MSK_BCST 0x04 /* Accept broadcasts */ +#define MSK_LB01 0x06 /* encoded loopback control */ +#define MSK_ATD 0x08 /* auto tx disable */ +#define MSK_OFST 0x10 /* collision offset enable */ + +/*-----receive status bits-----*/ +#define SMK_PRX 0x01 /* rx without error */ +#define SMK_CRC 0x02 /* CRC error */ +#define SMK_FAE 0x04 /* frame alignment error */ +#define SMK_FO 0x08 /* FIFO overrun */ +#define SMK_MPA 0x10 /* missed pkt */ +#define SMK_PHY 0x20 /* physical/multicase address */ +#define SMK_DIS 0x40 /* receiver disable. set in monitor mode */ +#define SMK_DEF 0x80 /* deferring */ + +/*-----transmit status bits-----*/ +#define SMK_PTX 0x01 /* tx without error */ +#define SMK_DFR 0x02 /* non deferred tx */ +#define SMK_COL 0x04 /* tx collided */ +#define SMK_ABT 0x08 /* tx abort because of excessive collisions */ +#define SMK_CRS 0x10 /* carrier sense lost */ +#define SMK_FU 0x20 /* FIFO underrun */ +#define SMK_CDH 0x40 /* collision detect heartbeat */ +#define SMK_OWC 0x80 /* out of window collision */ + diff --git a/c/src/lib/libbsp/i386/ts_386ex/network/Makefile.in b/c/src/lib/libbsp/i386/ts_386ex/network/Makefile.in new file mode 100644 index 0000000000..62b211072f --- /dev/null +++ b/c/src/lib/libbsp/i386/ts_386ex/network/Makefile.in @@ -0,0 +1,66 @@ +# +# $Id$ +# + +@SET_MAKE@ +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +top_builddir = ../../../../../../.. +subdir = c/src/lib/libbsp/i386/ts_386ex/network + +INSTALL = @INSTALL@ + +RTEMS_ROOT = $(top_srcdir)/@RTEMS_TOPdir@ +PROJECT_ROOT = @PROJECT_ROOT@ + +VPATH = @srcdir@ + +PGM=${ARCH}/network.rel + +# C source names, if any, go here -- minus the .c +C_PIECES=ne2000 +C_FILES=$(C_PIECES:%=%.c) +C_O_FILES=$(C_PIECES:%=${ARCH}/%.o) + +H_FILES= + +SRCS=$(C_FILES) $(H_FILES) +OBJS=$(C_O_FILES) + +include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg +include $(RTEMS_ROOT)/make/leaf.cfg + +# +# (OPTIONAL) Add local stuff here using += +# + +DEFINES += -D_COMPILING_BSD_KERNEL_ -DKERNEL -DINET -DNFS \ + -DDIAGNOSTIC -DBOOTP_COMPAT +CPPFLAGS += +CFLAGS += + +LD_PATHS += +LD_LIBS += +LDFLAGS += + +# +# Add your list of files to delete here. The config files +# already know how to delete some stuff, so you may want +# to just run 'make clean' first to see what gets missed. +# 'make clobber' already includes 'make clean' +# + +CLEAN_ADDITIONS += +CLOBBER_ADDITIONS += + +${PGM}: ${SRCS} ${OBJS} + $(make-rel) + +all: ${ARCH} $(SRCS) $(PGM) + +# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile +install: all + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status diff --git a/c/src/lib/libbsp/i386/ts_386ex/network/ne2000.c b/c/src/lib/libbsp/i386/ts_386ex/network/ne2000.c new file mode 100644 index 0000000000..666653f421 --- /dev/null +++ b/c/src/lib/libbsp/i386/ts_386ex/network/ne2000.c @@ -0,0 +1,1041 @@ +/* ne2k.c -- RTEMS NE2000 Ethernet driver. + * Written by Ian Lance Taylor, Zembu Labs. + * October, 1998. + * + * The license and distribution terms for this file may be + * found in found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + * + * Both the ne2000 and the wd80x3 are based on the National Semiconductor + * 8390 chip, so there is a fair amount of overlap between the two + * drivers. It would be possible in principle to combine some code into + * a separate set of subroutines called by both. In fact, the drivers in + * both OpenBSD and Linux work this way. I didn't bother, because for + * the relatively simple drivers used by RTEMS, the overlap is not + * especially large, and any reasonable use of subroutines would lead to + * slightly less efficient code. + + * This ne2000 driver uses two transmit buffers. While one packet is + * being transmitted over the Ethernet, RTEMS will upload another. Since + * uploading a packet to the ne2000 is rather slow, I don't think there + * is any point to having more than two transmit buffers. However, the + * code does make it possible, by changing NE_TX_BUFS, although that + * would of course reduce the number of receive buffers. + * + * I suspect that the wd80x3 driver would benefit slightly from copying + * the multiple transmit buffer code. However, I have no way to test + * that. + */ + +#include +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include + +#include + +/* Define this to force byte-wide data transfers with the NIC. This + is needed for boards like the TS-1325 386EX PC, which support only + an 8-bit PC/104 bus. Undefine this on a normal PC.*/ + +/* #define NE2000_BYTE_TRANSFERS */ + +/* Define this to print debugging messages with printk. */ + +/* #define DEBUG_NE2000 */ + +/* We expect to be able to read a complete packet into an mbuf. */ + +#if (MCLBYTES < 1520) +# error "Driver must have MCLBYTES >= 1520" +#endif + +/* The 8390 macro definitions in wd80x3.h expect RO to be defined. */ +#define RO 0 + +/* Minimum size of Ethernet packet. */ +#define ET_MINLEN 60 + +/* The number of NE2000 devices supported by this driver. */ + +#define NNEDRIVER 1 + +/* RTEMS event number used by the interrupt handler to signal the + driver task. This must not be any of the events used by the + network task synchronization. */ +#define INTERRUPT_EVENT RTEMS_EVENT_1 + +/* RTEMS event number used to start the transmit daemon. This must + not be the same as INTERRUPT_EVENT. */ +#define START_TRANSMIT_EVENT RTEMS_EVENT_2 + +/* Interrupts we want to handle from the device. */ + +#define NE_INTERRUPTS \ + (MSK_PRX | MSK_PTX | MSK_RXE | MSK_TXE | MSK_OVW | MSK_CNT) + +/* The size of a page in device memory. */ + +#define NE_PAGE_SIZE (256) + +/* The first page address in device memory. */ + +#define NE_START_PAGE (0x40) + +/* The last page address, plus 1. */ + +#define NE_STOP_PAGE (0x80) + +/* The number of pages used for a single transmit buffer. This is + 1536 bytes, enough for a full size packet. */ + +#define NE_TX_PAGES (6) + +/* The number of transmit buffers. We use two, so we can load one + packet while the other is being sent. */ + +#define NE_TX_BUFS (2) + +/* We use the first pages in memory as transmit buffers, and the + remaining ones as receive buffers. */ + +#define NE_FIRST_TX_PAGE (NE_START_PAGE) + +#define NE_FIRST_RX_PAGE (NE_FIRST_TX_PAGE + NE_TX_PAGES * NE_TX_BUFS) + +/* Data we store for each NE2000 device. */ + +struct ne_softc { + /* The bsdnet information structure. */ + struct arpcom arpcom; + + /* The interrupt request number. */ + unsigned int irno; + /* The base IO port number. */ + unsigned int port; + + /* Whether we accept broadcasts. */ + int accept_broadcasts; + + /* The thread ID of the transmit task. */ + rtems_id tx_daemon_tid; + /* The thread ID of the receive task. */ + rtems_id rx_daemon_tid; + + /* Whether we use byte-transfers with the device. */ + rtems_boolean byte_transfers; + + /* The number of memory buffers which the transmit daemon has loaded + with data to be sent, but which have not yet been completely + sent. */ + int inuse; + /* The index of the next available transmit memory buffer. */ + int nextavail; + /* The index of the next transmit buffer to send. */ + int nextsend; + /* Nonzero if the device is currently transmitting a packet. */ + int transmitting; + /* The length of the data stored in each transmit buffer. */ + int sendlen[NE_TX_BUFS]; + + /* Set if we have a packet overrun while receiving. */ + int overrun; + /* Set if we should resend after an overrun. */ + int resend; + + /* Statistics. */ + struct { + /* Number of packets received. */ + unsigned long rx_packets; + /* Number of packets sent. */ + unsigned long tx_packets; + /* Number of interrupts. */ + unsigned long interrupts; + /* Number of receive acknowledgements. */ + unsigned long rx_acks; + /* Number of transmit acknowledgements. */ + unsigned long tx_acks; + /* Number of packet overruns. */ + unsigned long overruns; + /* Number of frame errors. */ + unsigned long rx_frame_errors; + /* Number of CRC errors. */ + unsigned long rx_crc_errors; + /* Number of missed packets. */ + unsigned long rx_missed_errors; + } stats; +}; + +/* The list of NE2000 devices on this system. */ + +static struct ne_softc ne_softc[NNEDRIVER]; + +/* Find the NE2000 device which is attached at a particular interrupt + vector. */ + +static struct ne_softc * +ne_device_for_irno (int irno) +{ + int i; + + for (i = 0; i < NNEDRIVER; ++i) + { + if (ne_softc[i].irno == irno + && ne_softc[i].arpcom.ac_if.if_softc != NULL) + return &ne_softc[i]; + } + + return NULL; +} + +/* Read data from an NE2000 device. Read LEN bytes at ADDR, storing + them into P. */ + +static void +ne_read_data (struct ne_softc *sc, int addr, int len, unsigned char *p) +{ + unsigned int port = sc->port; + unsigned int dport = port + DATAPORT; + + outport_byte (port + CMDR, MSK_PG0 | MSK_RD2 | MSK_STA); + outport_byte (port + RBCR0, len); + outport_byte (port + RBCR1, len >> 8); + outport_byte (port + RSAR0, addr); + outport_byte (port + RSAR1, addr >> 8); + outport_byte (port + CMDR, MSK_PG0 | MSK_RRE | MSK_STA); + + if (sc->byte_transfers) + while (len > 0) { + unsigned char d; + + inport_byte (dport, d); + *p++ = d; + len--; + } + else /* word transfers */ + while (len > 0) { + unsigned short d; + + inport_word (dport, d); + *p++ = d; + *p++ = d >> 8; + len -= 2; + } + + outport_byte (port + ISR, MSK_RDC); +} + +/* Handle the current NE2000 status. This is called when the device + signals an interrupt. It is also called at other times while + NE2000 interrupts have been disabled. */ + +static void +ne_check_status (struct ne_softc *sc) +{ + unsigned int port = sc->port; + unsigned char status; + + /* It seems that we need to use a loop here, because if the NE2000 + signals an interrupt because packet transmission is complete, and + then receives a packet while interrupts are disabled, it seems to + sometimes fail to signal the interrupt for the received packet + when interrupts are reenabled. (Based on the behaviour of the + Realtek 8019AS chip). */ + + while (1) { + inport_byte (port + ISR, status); + if (status == 0) + break; + +#ifdef DEBUG_NE2000 + printk ("NE2000 status 0x%x (8259 enabled: %s; mask: %x)\n", status, + i8259s_cache & (1 << sc->irno) ? "no" : "yes", + i8259s_cache); +#endif + + /* Check for incoming packet overwrite. */ + if (status & MSK_OVW) { + unsigned char status2; + + ++sc->stats.overruns; + outport_byte (port + CMDR, MSK_PG0 | MSK_STP | MSK_RD2); + Wait_X_ms (2); + outport_byte (port + RBCR0, 0); + outport_byte (port + RBCR1, 0); + inport_byte (port + ISR, status2); + status |= status2 & (MSK_PTX | MSK_TXE); + outport_byte (port + TCR, MSK_LOOP); + outport_byte (port + CMDR, MSK_PG0 | MSK_STA | MSK_RD2); + sc->overrun = 1; + if ((status & (MSK_PTX | MSK_TXE)) == 0) + sc->resend = 1; + rtems_event_send (sc->rx_daemon_tid, INTERRUPT_EVENT); + } + + /* Check for transmitted packet. The transmit daemon may now be + able to send another packet to the device. */ + if ((status & (MSK_PTX | MSK_TXE)) != 0) { + ++sc->stats.tx_acks; + outport_byte (port + ISR, status & (MSK_PTX | MSK_TXE)); + --sc->inuse; + sc->transmitting = 0; + if (sc->inuse > 0 || (sc->arpcom.ac_if.if_flags & IFF_OACTIVE) != 0) + rtems_event_send (sc->tx_daemon_tid, START_TRANSMIT_EVENT); + } + + /* Check for received packet. */ + if ((status & (MSK_PRX | MSK_RXE)) != 0) { + ++sc->stats.rx_acks; + outport_byte (port + ISR, status & (MSK_PRX | MSK_RXE)); + rtems_event_send (sc->rx_daemon_tid, INTERRUPT_EVENT); + } + + /* Check for counter change. */ + if ((status & MSK_CNT) != 0) { + unsigned char add; + + inport_byte (port + CNTR0, add); + sc->stats.rx_frame_errors += add; + inport_byte (port + CNTR1, add); + sc->stats.rx_crc_errors += add; + inport_byte (port + CNTR2, add); + sc->stats.rx_missed_errors += add; + outport_byte (port + ISR, MSK_CNT); + } + } + + outport_byte (port + CMDR, MSK_PG0 | MSK_STA | MSK_RD2); +} + +/* Handle an NE2000 interrupt. */ + +static rtems_isr +ne_interrupt_handler (rtems_vector_number v) +{ + struct ne_softc *sc; + + sc = ne_device_for_irno (v); + if (sc == NULL) + return; + + ++sc->stats.interrupts; + + ne_check_status (sc); +} + +/* Turn NE2000 interrupts on. */ + +static void +ne_interrupt_on (const rtems_irq_connect_data *irq) +{ + struct ne_softc *sc; + +#ifdef DEBUG_NE2000 + printk ("ne_interrupt_on\n"); +#endif + sc = ne_device_for_irno (irq->name); + if (sc != NULL) + outport_byte (sc->port + IMR, NE_INTERRUPTS); +} + +/* Turn NE2000 interrupts off. See ne_interrupt_on. */ + +static void +ne_interrupt_off (const rtems_irq_connect_data *irq) +{ + struct ne_softc *sc; + +#ifdef DEBUG_NE2000 + printk ("ne_interrupt_off\n"); +#endif + sc = ne_device_for_irno (irq->name); + if (sc != NULL) + outport_byte (sc->port + IMR, 0); +} + +/* Return whether NE2000 interrupts are on. */ + +static int +ne_interrupt_is_on (const rtems_irq_connect_data *irq) +{ + return BSP_irq_enabled_at_i8259s (irq->name); +} + +/* Initialize the NE2000 hardware. */ + +static void +ne_init_hardware (struct ne_softc *sc) +{ + unsigned int port = sc->port; + int i; + rtems_irq_connect_data irq; + +#ifdef DEBUG_NE2000 + printk ("ne_init_hardware\n"); +#endif + + /* Initialize registers. */ + + outport_byte (port + CMDR, MSK_PG0 | MSK_RD2 | MSK_STP); + + if (sc->byte_transfers) { + outport_byte (port + DCR, MSK_FT10 | MSK_BMS); + } + else { + outport_byte (port + DCR, MSK_FT10 | MSK_BMS | MSK_WTS); + } + + outport_byte (port + RBCR0, 0); + outport_byte (port + RBCR1, 0); + outport_byte (port + RCR, MSK_MON); + outport_byte (port + TCR, MSK_LOOP); + outport_byte (port + IMR, 0); + outport_byte (port + ISR, 0xff); + outport_byte (port + PSTOP, NE_STOP_PAGE); + outport_byte (port + PSTART, NE_FIRST_RX_PAGE); + outport_byte (port + BNRY, NE_STOP_PAGE - 1); + + /* Set the Ethernet hardware address. */ + + outport_byte (port + CMDR, MSK_PG1 | MSK_RD2); + for (i = 0; i < ETHER_ADDR_LEN; ++i) + outport_byte (port + PAR + i, sc->arpcom.ac_enaddr[i]); + +#ifdef DEBUG_NE2000 + printk ("Using ethernet address: "); + for (i = 0; i < ETHER_ADDR_LEN; ++i) + printk("%x ",sc->arpcom.ac_enaddr[i]); + printk ("\n"); +#endif + + /* Clear the multicast address. */ + for (i = 0; i < MARsize; ++i) + outport_byte (port + MAR + i, 0); + + outport_byte (port + CURR, NE_FIRST_RX_PAGE); + + outport_byte (port + CMDR, MSK_PG0 | MSK_RD2); + + /* Put the device on line. */ + outport_byte (port + CMDR, MSK_PG0 | MSK_STA | MSK_RD2); + + /* Set up interrupts. */ + + irq.name = sc->irno; + irq.hdl = ne_interrupt_handler; + irq.on = ne_interrupt_on; + irq.off = ne_interrupt_off; + irq.isOn = ne_interrupt_is_on; + + if (! BSP_install_rtems_irq_handler (&irq)) + rtems_panic ("Can't attach NE interrupt handler for irq %d.\n", + sc->irno); + + /* Prepare to receive packets. */ + + outport_byte (port + TCR, 0); + outport_byte (port + RCR, (sc->accept_broadcasts ? MSK_AB : 0)); +} + +/* The NE2000 packet receive daemon. This task is started when the + NE2000 driver is initialized. */ + +static void +ne_rx_daemon (void *arg) +{ + struct ne_softc *sc = (struct ne_softc *) arg; + struct ifnet *ifp = &sc->arpcom.ac_if; + unsigned int port = sc->port; + unsigned int dport = port + DATAPORT; + + while (1) { + rtems_event_set events; + + /* Wait for the interrupt handler to tell us that there is a + packet ready to receive. */ + rtems_bsdnet_event_receive (INTERRUPT_EVENT, + RTEMS_WAIT | RTEMS_EVENT_ANY, + RTEMS_NO_TIMEOUT, + &events); + + /* Don't let the device interrupt us now. */ + outport_byte (port + IMR, 0); + + while (1) { + unsigned char startpage, currpage; + unsigned short statnext, len; + int next; + struct mbuf *m; + unsigned char *p; + int startaddr; + int toend; + struct ether_header *eh; + + inport_byte (port + BNRY, startpage); + + outport_byte (port + CMDR, MSK_PG1 | MSK_RD2); + inport_byte (port + CURR, currpage); + outport_byte (port + CMDR, MSK_PG0 | MSK_RD2); + + ++startpage; + if (startpage >= NE_STOP_PAGE) + startpage = NE_FIRST_RX_PAGE; + + if (startpage == currpage) + break; + +#ifdef DEBUG_NE2000 + printk ("ne_rx_daemon: start page %x; current page %x\n", + startpage, currpage); +#endif + + /* Read the buffer header. This is 1 byte receive status, 1 + byte page of next buffer, 2 bytes length. */ + outport_byte (port + CMDR, MSK_PG0 | MSK_RD2 | MSK_STA); + outport_byte (port + RBCR0, 4); + outport_byte (port + RBCR1, 0); + outport_byte (port + RSAR0, 0); + outport_byte (port + RSAR1, startpage); + outport_byte (port + CMDR, MSK_PG0 | MSK_RRE | MSK_STA); + + if (sc->byte_transfers) { + unsigned char data; + + inport_byte (dport, data); /* Throw away status */ + inport_byte (dport, data); + next = data; + + inport_byte (dport, data); + len = data; + inport_byte (dport, data); + len |= data << 8; + } + else { /* Word transfers */ + inport_word (dport, statnext); + inport_word (dport, len); + + next = statnext >> 8; + } + + outport_byte (port + ISR, MSK_RDC); + + if (next >= NE_STOP_PAGE) + next = NE_FIRST_RX_PAGE; + + /* The first four bytes of the length are the buffer header. */ + len -= 4; + startaddr = startpage * NE_PAGE_SIZE + 4; + + MGETHDR (m, M_WAIT, MT_DATA); + MCLGET (m, M_WAIT); + m->m_pkthdr.rcvif = ifp; + + p = mtod (m, unsigned char *); + m->m_len = m->m_pkthdr.len = len - sizeof (struct ether_header); + + toend = NE_STOP_PAGE * NE_PAGE_SIZE - startaddr; + if (toend < len) { + ne_read_data (sc, startaddr, toend, p); + p += toend; + len -= toend; + startaddr = NE_FIRST_RX_PAGE * NE_PAGE_SIZE; + } + + if (len > 0) + ne_read_data (sc, startaddr, len, p); + + eh = mtod (m, struct ether_header *); + m->m_data += sizeof (struct ether_header); + ether_input (ifp, eh, m); + + ++sc->stats.rx_packets; + + outport_byte (port + BNRY, next - 1); + } + + if (sc->overrun) { + outport_byte (port + ISR, MSK_OVW); + outport_byte (port + TCR, 0); + if (sc->resend) + outport_byte (port + CMDR, MSK_PG0 | MSK_TXP | MSK_RD2 | MSK_STA); + sc->resend = 0; + sc->overrun = 0; + } + + /* Reenable device interrupts. */ + outport_byte (port + IMR, NE_INTERRUPTS); + } +} + +/* Load an NE2000 packet onto the device. */ + +static void +ne_loadpacket (struct ne_softc *sc, struct mbuf *m) +{ + unsigned int port = sc->port; + unsigned int dport = port + DATAPORT; + struct mbuf *mhold = m; + int leftover; + unsigned char leftover_data; + int timeout; + +#ifdef DEBUG_NE2000 + printk ("Uploading NE2000 packet\n"); +#endif + + /* Reset remote DMA complete flag. */ + outport_byte (port + ISR, MSK_RDC); + + /* Write out the count. */ + outport_byte (port + RBCR0, m->m_pkthdr.len); + outport_byte (port + RBCR1, m->m_pkthdr.len >> 8); + + sc->sendlen[sc->nextavail] = m->m_pkthdr.len; + + /* Tell the device which address we want to write to. */ + outport_byte (port + RSAR0, 0); + outport_byte (port + RSAR1, + NE_FIRST_TX_PAGE + (sc->nextavail * NE_TX_PAGES)); + + /* Set up the write. */ + outport_byte (port + CMDR, MSK_PG0 | MSK_RWR | MSK_STA); + + /* Transfer the mbuf chain to device memory. NE2000 devices require + that the data be transferred as words, so we need to handle odd + length mbufs. Never occurs if we force byte transfers. */ + + leftover = 0; + leftover_data = '\0'; + + for (; m != NULL; m = m->m_next) { + int len; + unsigned char *data; + + len = m->m_len; + if (len == 0) + continue; + + data = mtod (m, unsigned char *); + + if (leftover) { + unsigned char next; + + /* Data left over from previous mbuf in chain. */ + next = *data++; + --len; + outport_word (dport, leftover_data | (next << 8)); + leftover = 0; + } + + /* If using byte transfers, len always ends up as zero so + there are no leftovers. */ + + if (sc->byte_transfers) + while (len > 0) { + outport_byte (dport, *data++); + len--; + } + else + while (len > 1) { + outport_word (dport, data[0] | (data[1] << 8)); + data += 2; + len -= 2; + } + + if (len > 0) + { + leftover = 1; + leftover_data = *data++; + } + } + + if (leftover) + outport_word (dport, leftover_data); + + m_freem (mhold); + + /* Wait for the device to complete accepting the data, with a + limiting counter so that we don't wait too long. */ + for (timeout = 0; timeout < 100; ++timeout) + { + unsigned char status; + + inport_byte (port + ISR, status); + +#ifdef DEBUG_NE2000 + if ((status &~ MSK_RDC) != 0) + printk ("Status 0x%x while waiting for acknowledgement of uploaded packet\n", + status); +#endif + + if ((status & MSK_RDC) != 0) { + outport_byte (port + ISR, MSK_RDC); + break; + } + } + + if (timeout >= 100) + printk ("Timed out waiting for acknowledgement of uploaded NE2000 packet\n"); + + ++sc->nextavail; + if (sc->nextavail == NE_TX_BUFS) + sc->nextavail = 0; +} + +/* Tell the NE2000 to transmit a buffer whose contents we have already + loaded onto the device. */ + +static void +ne_transmit (struct ne_softc *sc) +{ + unsigned int port = sc->port; + int len; + +#ifdef DEBUG_NE2000 + printk ("Transmitting NE2000 packet\n"); +#endif + + len = sc->sendlen[sc->nextsend]; + if (len < ET_MINLEN) + len = ET_MINLEN; + outport_byte (port + TBCR0, len); + outport_byte (port + TBCR1, len >> 8); + + outport_byte (port + TPSR, NE_FIRST_TX_PAGE + (sc->nextsend * NE_TX_PAGES)); + + outport_byte (port + CMDR, MSK_PG0 | MSK_TXP | MSK_RD2 | MSK_STA); + + ++sc->nextsend; + if (sc->nextsend == NE_TX_BUFS) + sc->nextsend = 0; + + ++sc->stats.tx_packets; +} + +/* The NE2000 packet transmit daemon. This task is started when the + NE2000 driver is initialized. */ + +static void +ne_tx_daemon (void *arg) +{ + struct ne_softc *sc = (struct ne_softc *) arg; + unsigned int port = sc->port; + struct ifnet *ifp = &sc->arpcom.ac_if; + + while (1) { + rtems_event_set events; + + /* Wait for a packet to be ready for sending, or for there to be + room for another packet in the device memory. */ + rtems_bsdnet_event_receive (START_TRANSMIT_EVENT, + RTEMS_EVENT_ANY | RTEMS_WAIT, + RTEMS_NO_TIMEOUT, + &events); + +#ifdef DEBUG_NE2000 + printk ("ne_tx_daemon\n"); +#endif + + /* This daemon handles both uploading data onto the device and + telling the device to transmit data which has been uploaded. + These are separate tasks, because while the device is + transmitting one buffer we will upload another. */ + + /* Don't let the device interrupt us now. */ + outport_byte (port + IMR, 0); + + while (1) { + struct mbuf *m; + + /* If the device is not transmitting a packet, and we have + uploaded a packet, tell the device to transmit it. */ + if (! sc->transmitting && sc->inuse > 0) { + sc->transmitting = 1; + ne_transmit (sc); + } + + /* If we don't have any more buffers to send, quit now. */ + if (ifp->if_snd.ifq_head == NULL) { + ifp->if_flags &= ~IFF_OACTIVE; + break; + } + + /* Allocate a buffer to load data into. If there are none + available, quit until a buffer has been transmitted. */ + if (sc->inuse >= NE_TX_BUFS) + break; + + ++sc->inuse; + + IF_DEQUEUE (&ifp->if_snd, m); + if (m == NULL) + panic ("ne_tx_daemon"); + + ne_loadpacket (sc, m); + + /* Check the device status. It may have finished transmitting + the last packet. */ + ne_check_status (sc); + } + + /* Reenable device interrupts. */ + outport_byte (port + IMR, NE_INTERRUPTS); + } +} + +/* Start sending an NE2000 packet. */ + +static void +ne_start (struct ifnet *ifp) +{ + struct ne_softc *sc = ifp->if_softc; + + /* Tell the transmit daemon to wake up and send a packet. */ + rtems_event_send (sc->tx_daemon_tid, START_TRANSMIT_EVENT); + ifp->if_flags |= IFF_OACTIVE; +} + +/* Initialize and start and NE2000. */ + +static void +ne_init (void *arg) +{ + struct ne_softc *sc = (struct ne_softc *) arg; + struct ifnet *ifp = &sc->arpcom.ac_if; + + if (sc->tx_daemon_tid == 0) { + sc->inuse = 0; + sc->nextavail = 0; + sc->nextsend = 0; + sc->transmitting = 0; + + ne_init_hardware (sc); + + sc->tx_daemon_tid = rtems_bsdnet_newproc ("SCtx", 4096, ne_tx_daemon, sc); + sc->rx_daemon_tid = rtems_bsdnet_newproc ("SCrx", 4096, ne_rx_daemon, sc); + } + + ifp->if_flags |= IFF_RUNNING; +} + +/* Stop an NE2000. */ + +static void +ne_stop (struct ne_softc *sc) +{ + unsigned int port = sc->port; + int i; + + sc->arpcom.ac_if.if_flags &= ~IFF_RUNNING; + + /* Stop everything. */ + outport_byte (port + CMDR, MSK_STP | MSK_RD2); + + /* Wait for the interface to stop, using I as a time limit. */ + for (i = 0; i < 5000; ++i) + { + unsigned char status; + + inport_byte (port + ISR, status); + if ((status & MSK_RST) != 0) + break; + } + + sc->inuse = 0; + sc->nextavail = 0; + sc->nextsend = 0; + sc->transmitting = 0; +} + +/* Show NE2000 interface statistics. */ + +static void +ne_stats (struct ne_softc *sc) +{ + printf (" Received packets: %-8lu", sc->stats.rx_packets); + printf (" Transmitted packets: %-8lu\n", sc->stats.tx_packets); + printf (" Receive acks: %-8lu", sc->stats.rx_acks); + printf (" Transmit acks: %-8lu\n", sc->stats.tx_acks); + printf (" Packet overruns: %-8lu", sc->stats.overruns); + printf (" Frame errors: %-8lu\n", sc->stats.rx_frame_errors); + printf (" CRC errors: %-8lu", sc->stats.rx_crc_errors); + printf (" Missed packets: %-8lu\n", sc->stats.rx_missed_errors); + printf (" Interrupts: %-8lu\n", sc->stats.interrupts); +} + +/* NE2000 driver ioctl handler. */ + +static int +ne_ioctl (struct ifnet *ifp, int command, caddr_t data) +{ + struct ne_softc *sc = ifp->if_softc; + int error = 0; + + switch (command) { + case SIOCGIFADDR: + case SIOCSIFADDR: + error = ether_ioctl (ifp, command, data); + break; + + case SIOCSIFFLAGS: + switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) { + case IFF_RUNNING: + ne_stop (sc); + break; + + case IFF_UP: + ne_init (sc); + break; + + case IFF_UP | IFF_RUNNING: + ne_stop (sc); + ne_init (sc); + break; + + default: + break; + } + break; + + case SIO_RTEMS_SHOW_STATS: + ne_stats (sc); + break; + + /* FIXME: Multicast commands must be added here. */ + + default: + error = EINVAL; + break; + } + + return error; +} + +/* Attach an NE2000 driver to the system. */ + +int +rtems_ne_driver_attach (struct rtems_bsdnet_ifconfig *config) +{ + int i; + struct ne_softc *sc; + struct ifnet *ifp; + int mtu; + + /* Find a free driver. */ + sc = NULL; + for (i = 0; i < NNEDRIVER; ++i) { + sc = &ne_softc[i]; + ifp = &sc->arpcom.ac_if; + if (ifp->if_softc == NULL) + break; + } + + if (sc == NULL) { + printf ("Too many NE2000 drivers.\n"); + return 0; + } + + memset (sc, 0, sizeof *sc); + + /* Check whether we do byte-wide or word-wide transfers. */ + +#ifdef NE2000_BYTE_TRANSFERS + sc->byte_transfers = TRUE; +#else + sc->byte_transfers = FALSE; +#endif + + /* Handle the options passed in by the caller. */ + + if (config->mtu != 0) + mtu = config->mtu; + else + mtu = ETHERMTU; + + if (config->irno != 0) + sc->irno = config->irno; + else { + /* We use 5 as the default IRQ. */ + sc->irno = 5; + } + + if (config->port != 0) + sc->port = config->port; + else { + /* We use 0x300 as the default IO port number. */ + sc->port = 0x300; + } + + sc->accept_broadcasts = ! config->ignore_broadcast; + + if (config->hardware_address != NULL) + memcpy (sc->arpcom.ac_enaddr, config->hardware_address, + ETHER_ADDR_LEN); + else + { + unsigned char prom[16]; + int ia; + + /* Read the PROM to get the Ethernet hardware address. */ + + outport_byte (sc->port + CMDR, MSK_PG0 | MSK_RD2 | MSK_STP); + + if (sc->byte_transfers) { + outport_byte (sc->port + DCR, MSK_FT10 | MSK_BMS); + } + else { + outport_byte (sc->port + DCR, MSK_FT10 | MSK_BMS | MSK_WTS); + } + + outport_byte (sc->port + RBCR0, 0); + outport_byte (sc->port + RBCR1, 0); + outport_byte (sc->port + RCR, MSK_MON); + outport_byte (sc->port + TCR, MSK_LOOP); + outport_byte (sc->port + IMR, 0); + outport_byte (sc->port + ISR, 0xff); + + ne_read_data (sc, 0, sizeof prom, prom); + + outport_byte (sc->port + CMDR, MSK_PG0 | MSK_RD2 | MSK_STP); + + for (ia = 0; ia < ETHER_ADDR_LEN; ++ia) + sc->arpcom.ac_enaddr[ia] = prom[ia * 2]; + } + + /* Set up the network interface. */ + + ifp->if_softc = sc; + ifp->if_unit = i + 1; + ifp->if_name = "ne"; + ifp->if_mtu = mtu; + ifp->if_init = ne_init; + ifp->if_ioctl = ne_ioctl; + ifp->if_start = ne_start; + ifp->if_output = ether_output; + ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX; + if (ifp->if_snd.ifq_maxlen == 0) + ifp->if_snd.ifq_maxlen = ifqmaxlen; + + /* Attach the interface. */ + + if_attach (ifp); + ether_ifattach (ifp); + + return 1; +} diff --git a/c/src/lib/libbsp/i386/ts_386ex/start/80386ex.h b/c/src/lib/libbsp/i386/ts_386ex/start/80386ex.h new file mode 100644 index 0000000000..24e4b9a8ee --- /dev/null +++ b/c/src/lib/libbsp/i386/ts_386ex/start/80386ex.h @@ -0,0 +1,254 @@ +/* + * Submitted by: + * + * Erik Ivanenko + * University of Toronto + * erik.ivanenko@utoronto.ca + * + * 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$ + */ + +/* REMAP ADDRESSING Registers */ +#define REMAPCFGH 0x0023 +#define REMAPCFGL 0x0022 +#define REMAPCFG 0x0022 +/* INTERRUPT CONTROL REGISTERS -- SLOT 15 ADDRESSES */ +#define ICW1M 0xF020 +#define ICW1S 0xF0A0 +#define ICW2M 0xF021 +#define ICW2S 0xF0A1 +#define ICW3M 0xF021 +#define ICW3S 0xF0A1 +#define ICW4M 0xF021 +#define ICW4S 0xF0A1 +#define OCW1M 0xF021 +#define OCW1S 0xF0A1 +#define OCW2M 0xF020 +#define OCW2S 0xF0A0 +#define OCW3M 0xF020 +#define OCW3S 0xF0A0 +/* INTERRUPT CONTROL REGISTERS -- SLOT 0 ADDRESSES */ +#define ICW1MDOS 0x0020 +#define ICW1SDOS 0x00A0 +#define ICW2MDOS 0x0021 +#define ICW2SDOS 0x00A1 +#define ICW3MDOS 0x0021 +#define ICW3SDOS 0x00A1 +#define ICW4MDOS 0x0021 +#define ICW4SDOS 0x00A1 +#define OCW1MDOS 0x0021 +#define OCW1SDOS 0x00A1 +#define OCW2MDOS 0x0020 +#define OCW2SDOS 0x00A0 +#define OCW3MDOS 0x0020 +#define OCW3SDOS 0x00A0 + + +/* CONFIGURATION Registers */ +#define DMACFG 0xF830 +#define INTCFG 0xF832 +#define TMRCFG 0xF834 +#define SIOCFG 0xF836 +#define P1CFG 0xF820 +#define P2CFG 0xF822 +#define P3CFG 0xF824 +#define PINCFG 0xF826 + +/* WATCHDOG TIMER Registers */ +#define WDTRLDH 0xF4C0 +#define WDTRLDL 0xF4C2 +#define WDTCNTH 0xF4C4 +#define WDTCNTL 0xF4C6 +#define WDTCLR 0xF4C8 +#define WDTSTATUS 0xF4CA + +/* TIMER CONTROL REGISTERS -- SLOT 15 ADDRESSES */ +#define TMR0 0xF040 +#define TMR1 0xF041 +#define TMR2 0xF042 +#define TMRCON 0xF043 +/* TIMER CONTROL REGISTERS -- SLOT 0 ADDRESSES */ +#define TMR0DOS 0x0040 +#define TMR1DOS 0x0041 +#define TMR2DOS 0x0042 +#define TMRCONDOS 0x0043 + +/* INPUT/OUTPUT PORT UNIT Registers */ +#define P1PIN 0xF860 +#define P1LTC 0xF862 +#define P1DIR 0xF864 +#define P2PIN 0xF868 +#define P2LTC 0xF86A +#define P2DIR 0xF86C +#define P3PIN 0xF870 +#define P3LTC 0xF872 +#define P3DIR 0xF874 + +/* ASYNCHRONOUS SERIAL CHANNEL 0 -- SLOT 15 ADDRESSES */ +#define RBR0 0xF4F8 +#define THR0 0xF4F8 +#define TBR0 0xF4F8 +#define DLL0 0xF4F8 +#define IER0 0xF4F9 +#define DLH0 0xF4F9 +#define IIR0 0xF4FA +#define LCR0 0xF4FB +#define MCR0 0xF4FC +#define LSR0 0xF4FD +#define MSR0 0xF4FE +#define SCR0 0xF4FF +/* ASYNCHRONOUS SERIAL CHANNEL 0 -- SLOT 0 ADDRESSES */ +#define RBR0DOS 0x03F8 +#define THR0DOS 0x03F8 +#define TBR0DOS 0x03F8 +#define DLL0DOS 0x03F8 +#define IER0DOS 0x03F9 +#define DLH0DOS 0x03F9 +#define IIR0DOS 0x03FA +#define LCR0DOS 0x03FB +#define MCR0DOS 0x03FC +#define LSR0DOS 0x03FD +#define MSR0DOS 0x03FE +#define SCR0DOS 0x03FF + +/* ASYNCHRONOUS SERIAL CHANNEL 1 -- SLOT 15 ADDRESSES */ +#define RBR1 0xF8F8 +#define THR1 0xF8F8 +#define TBR1 0XF8F8 +#define DLL1 0xF8F8 +#define IER1 0xF8F9 +#define DLH1 0xF8F9 +#define IIR1 0xF8FA +#define LCR1 0xF8FB +#define MCR1 0xF8FC +#define LSR1 0xF8FD +#define MSR1 0xF8FE +#define SCR1 0xF8FF +/* ASYNCHRONOUS SERIAL CHANNEL 1 -- SLOT 0 ADDRESSES */ +#define RBR1DOS 0x02F8 +#define THR1DOS 0x02F8 +#define TBR1DOS 0x02F8 +#define DLL1DOS 0x02F8 +#define IER1DOS 0x02F9 +#define DLH1DOS 0x02F9 +#define IIR1DOS 0x02FA +#define LCR1DOS 0x02FB +#define MCR1DOS 0x02FC +#define LSR1DOS 0x02FD +#define MSR1DOS 0x02FE +#define SCR1DOS 0x02FF + +/* SYNCHRONOUS SERIAL CHANNEL REGISTERS */ +#define SSIOTBUF 0xF480 +#define SSIORBUF 0xF482 +#define SSIOBAUD 0xF484 +#define SSIOCON1 0xF486 +#define SSIOCON2 0xF488 +#define SSIOCTR 0xF48A + +/* CHIP SELECT UNIT Registers */ +#define CS0ADL 0xF400 +#define CS0ADH 0xF402 +#define CS0MSKL 0xF404 +#define CS0MSKH 0xF406 +#define CS1ADL 0xF408 +#define CS1ADH 0xF40A +#define CS1MSKL 0xF40C +#define CS1MSKH 0xF40E +#define CS2ADL 0xF410 +#define CS2ADH 0xF412 +#define CS2MSKL 0xF414 +#define CS2MSKH 0xF416 +#define CS3ADL 0xF418 +#define CS3ADH 0xF41A +#define CS3MSKL 0xF41C +#define CS3MSKH 0xF41E +#define CS4ADL 0xF420 +#define CS4ADH 0xF422 +#define CS4MSKL 0xF424 +#define CS4MSKH 0xF426 +#define CS5ADL 0xF428 +#define CS5ADH 0xF42A +#define CS5MSKL 0xF42C +#define CS5MSKH 0xF42E +#define CS6ADL 0xF430 +#define CS6ADH 0xF432 +#define CS6MSKL 0xF434 +#define CS6MSKH 0xF436 +#define UCSADL 0xF438 +#define UCSADH 0xF43A +#define UCSMSKL 0xF43C +#define UCSMSKH 0xF43E + +/* REFRESH CONTROL UNIT Registers */ + +#define RFSBAD 0xF4A0 +#define RFSCIR 0xF4A2 +#define RFSCON 0xF4A4 +#define RFSADD 0xF4A6 + +/* POWER MANAGEMENT CONTROL Registers */ + +#define PWRCON 0xF800 +#define CLKPRS 0xF804 + +/* DMA UNIT REGISTERS -- SLOT 15 ADDRESSES */ +#define DMA0TAR 0xF000 +#define DMA0BYC 0xF001 +#define DMA1TAR 0xF002 +#define DMA1BYC 0xF003 +#define DMACMD1 0xF008 +#define DMASTS 0xF008 +#define DMASRR 0xF009 +#define DMAMSK 0xF00A +#define DMAMOD1 0xF00B +#define DMACLRBP 0xF00C +#define DMACLR 0xF00D +#define DMACLRMSK 0xF00E +#define DMAGRPMSK 0xF00F +#define DMA0REQL 0xF010 +#define DMA0REQH 0xF011 +#define DMA1REQL 0xF012 +#define DMA1REQH 0xF013 +#define DMABSR 0xF018 +#define DMACHR 0xF019 +#define DMAIS 0xF019 +#define DMACMD2 0xF01A +#define DMAMOD2 0xF01B +#define DMAIEN 0xF01C +#define DMAOVFE 0xF01D +#define DMACLRTC 0xF01E +#define DMA1TARPL 0xF083 +#define DMA1TARPH 0xF085 +#define DMA0TARPH 0xF086 +#define DMA0TARPL 0xF087 +#define DMA0BYCH 0xF098 +#define DMA1BYCH 0xF099 + +/* DMA UNIT REGISTERS -- SLOT 0 ADDRESSES */ +#define DMA0TARDOS 0x0000 +#define DMA0BYCDOS 0x0001 +#define DMA1TARDOS 0x0002 +#define DMA1BYCDOS 0x0003 +#define DMACMD1DOS 0x0008 +#define DMASTSDOS 0x0008 +#define DMASRRDOS 0x0009 +#define DMAMSKDOS 0x000A +#define DMAMOD1DOS 0x000B +#define DMACLRBPDOS 0x000C +#define DMACLRDOS 0x000D +#define DMACLRMSKDOS 0x000E +#define DMAGRPMSKDOS 0x000F +#define DMA1TARPLDOS 0x0083 +#define DMA0TARPLDOS 0x0087 + +/* A20GATE AND FAST CPU RESET -- SLOT 15 ADDRESS */ +#define PORT92 0xF092 +/* A20GATE AND FAST CPU RESET -- SLOT 0 ADDRESS */ +#define PORT92DOS 0x0092 + +/* end of include file */ diff --git a/c/src/lib/libbsp/i386/ts_386ex/start/80386ex.inc b/c/src/lib/libbsp/i386/ts_386ex/start/80386ex.inc new file mode 100644 index 0000000000..798dda4215 --- /dev/null +++ b/c/src/lib/libbsp/i386/ts_386ex/start/80386ex.inc @@ -0,0 +1,252 @@ +/* + * Submitted by: + * + * Erik Ivanenko + * University of Toronto + * erik.ivanenko@utoronto.ca + * + * 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$ + */ + +/* REMAP ADDRESSING Registers */ +.set REMAPCFGH , 0x0023 +.set REMAPCFGL , 0x0022 +.set REMAPCFG , 0x0022 +/* INTERRUPT CONTROL REGISTERS -- SLOT 15 ADDRESSES */ +.set ICW1M , 0xF020 +.set ICW1S , 0xF0A0 +.set ICW2M , 0xF021 +.set ICW2S , 0xF0A1 +.set ICW3M , 0xF021 +.set ICW3S , 0xF0A1 +.set ICW4M , 0xF021 +.set ICW4S , 0xF0A1 +.set OCW1M , 0xF021 +.set OCW1S , 0xF0A1 +.set OCW2M , 0xF020 +.set OCW2S , 0xF0A0 +.set OCW3M , 0xF020 +.set OCW3S , 0xF0A0 +/* INTERRUPT CONTROL REGISTERS -- SLOT 0 ADDRESSES */ +.set ICW1MDOS , 0x0020 +.set ICW1SDOS , 0x00A0 +.set ICW2MDOS , 0x0021 +.set ICW2SDOS , 0x00A1 +.set ICW3MDOS , 0x0021 +.set ICW3SDOS , 0x00A1 +.set ICW4MDOS , 0x0021 +.set ICW4SDOS , 0x00A1 +.set OCW1MDOS , 0x0021 +.set OCW1SDOS , 0x00A1 +.set OCW2MDOS , 0x0020 +.set OCW2SDOS , 0x00A0 +.set OCW3MDOS , 0x0020 +.set OCW3SDOS , 0x00A0 + + +/* CONFIGURATION Registers */ +.set DMACFG , 0xF830 +.set INTCFG , 0xF832 +.set TMRCFG , 0xF834 +.set SIOCFG , 0xF836 +.set P1CFG , 0xF820 +.set P2CFG , 0xF822 +.set P3CFG , 0xF824 +.set PINCFG , 0xF826 + +/* WATCHDOG TIMER Registers */ +.set WDTRLDH , 0xF4C0 +.set WDTRLDL , 0xF4C2 +.set WDTCNTH , 0xF4C4 +.set WDTCNTL , 0xF4C6 +.set WDTCLR , 0xF4C8 +.set WDTSTATUS , 0xF4CA + +/* TIMER CONTROL REGISTERS -- SLOT 15 ADDRESSES */ +.set TMR0 , 0xF040 +.set TMR1 , 0xF041 +.set TMR2 , 0xF042 +.set TMRCON , 0xF043 +/* TIMER CONTROL REGISTERS -- SLOT 0 ADDRESSES */ +.set TMR0DOS , 0x0040 +.set TMR1DOS , 0x0041 +.set TMR2DOS , 0x0042 +.set TMRCONDOS , 0x0043 + +/* INPUT/OUTPUT PORT UNIT Registers */ +.set P1PIN , 0xF860 +.set P1LTC , 0xF862 +.set P1DIR , 0xF864 +.set P2PIN , 0xF868 +.set P2LTC , 0xF86A +.set P2DIR , 0xF86C +.set P3PIN , 0xF870 +.set P3LTC , 0xF872 +.set P3DIR , 0xF874 + +/* ASYNCHRONOUS SERIAL CHANNEL 0 -- SLOT 15 ADDRESSES */ +.set RBR0 , 0xF4F8 +.set THR0 , 0xF4F8 +.set TBR0 , 0xF4F8 +.set DLL0 , 0xF4F8 +.set IER0 , 0xF4F9 +.set DLH0 , 0xF4F9 +.set IIR0 , 0xF4FA +.set LCR0 , 0xF4FB +.set MCR0 , 0xF4FC +.set LSR0 , 0xF4FD +.set MSR0 , 0xF4FE +.set SCR0 , 0xF4FF +/* ASYNCHRONOUS SERIAL CHANNEL 0 -- SLOT 0 ADDRESSES */ +.set RBR0DOS , 0x03F8 +.set THR0DOS , 0x03F8 +.set TBR0DOS , 0x03F8 +.set DLL0DOS , 0x03F8 +.set IER0DOS , 0x03F9 +.set DLH0DOS , 0x03F9 +.set IIR0DOS , 0x03FA +.set LCR0DOS , 0x03FB +.set MCR0DOS , 0x03FC +.set LSR0DOS , 0x03FD +.set MSR0DOS , 0x03FE +.set SCR0DOS , 0x03FF + +/* ASYNCHRONOUS SERIAL CHANNEL 1 -- SLOT 15 ADDRESSES */ +.set RBR1 , 0xF8F8 +.set THR1 , 0xF8F8 +.set TBR1 , 0XF8F8 +.set DLL1 , 0xF8F8 +.set IER1 , 0xF8F9 +.set DLH1 , 0xF8F9 +.set IIR1 , 0xF8FA +.set LCR1 , 0xF8FB +.set MCR1 , 0xF8FC +.set LSR1 , 0xF8FD +.set MSR1 , 0xF8FE +.set SCR1 , 0xF8FF +/* ASYNCHRONOUS SERIAL CHANNEL 1 -- SLOT 0 ADDRESSES */ +.set RBR1DOS , 0x02F8 +.set THR1DOS , 0x02F8 +.set TBR1DOS , 0x02F8 +.set DLL1DOS , 0x02F8 +.set IER1DOS , 0x02F9 +.set DLH1DOS , 0x02F9 +.set IIR1DOS , 0x02FA +.set LCR1DOS , 0x02FB +.set MCR1DOS , 0x02FC +.set LSR1DOS , 0x02FD +.set MSR1DOS , 0x02FE +.set SCR1DOS , 0x02FF + +/* SYNCHRONOUS SERIAL CHANNEL REGISTERS */ +.set SSIOTBUF , 0xF480 +.set SSIORBUF , 0xF482 +.set SSIOBAUD , 0xF484 +.set SSIOCON1 , 0xF486 +.set SSIOCON2 , 0xF488 +.set SSIOCTR , 0xF48A + +/* CHIP SELECT UNIT Registers */ +.set CS0ADL , 0xF400 +.set CS0ADH , 0xF402 +.set CS0MSKL , 0xF404 +.set CS0MSKH , 0xF406 +.set CS1ADL , 0xF408 +.set CS1ADH , 0xF40A +.set CS1MSKL , 0xF40C +.set CS1MSKH , 0xF40E +.set CS2ADL , 0xF410 +.set CS2ADH , 0xF412 +.set CS2MSKL , 0xF414 +.set CS2MSKH , 0xF416 +.set CS3ADL , 0xF418 +.set CS3ADH , 0xF41A +.set CS3MSKL , 0xF41C +.set CS3MSKH , 0xF41E +.set CS4ADL , 0xF420 +.set CS4ADH , 0xF422 +.set CS4MSKL , 0xF424 +.set CS4MSKH , 0xF426 +.set CS5ADL , 0xF428 +.set CS5ADH , 0xF42A +.set CS5MSKL , 0xF42C +.set CS5MSKH , 0xF42E +.set CS6ADL , 0xF430 +.set CS6ADH , 0xF432 +.set CS6MSKL , 0xF434 +.set CS6MSKH , 0xF436 +.set UCSADL , 0xF438 +.set UCSADH , 0xF43A +.set UCSMSKL , 0xF43C +.set UCSMSKH , 0xF43E + +/* REFRESH CONTROL UNIT Registers */ + +.set RFSBAD , 0xF4A0 +.set RFSCIR , 0xF4A2 +.set RFSCON , 0xF4A4 +.set RFSADD , 0xF4A6 + +/* POWER MANAGEMENT CONTROL Registers */ + +.set PWRCON , 0xF800 +.set CLKPRS , 0xF804 + +/* DMA UNIT REGISTERS -- SLOT 15 ADDRESSES */ +.set DMA0TAR , 0xF000 +.set DMA0BYC , 0xF001 +.set DMA1TAR , 0xF002 +.set DMA1BYC , 0xF003 +.set DMACMD1 , 0xF008 +.set DMASTS , 0xF008 +.set DMASRR , 0xF009 +.set DMAMSK , 0xF00A +.set DMAMOD1 , 0xF00B +.set DMACLRBP , 0xF00C +.set DMACLR , 0xF00D +.set DMACLRMSK , 0xF00E +.set DMAGRPMSK , 0xF00F +.set DMA0REQL , 0xF010 +.set DMA0REQH , 0xF011 +.set DMA1REQL , 0xF012 +.set DMA1REQH , 0xF013 +.set DMABSR , 0xF018 +.set DMACHR , 0xF019 +.set DMAIS , 0xF019 +.set DMACMD2 , 0xF01A +.set DMAMOD2 , 0xF01B +.set DMAIEN , 0xF01C +.set DMAOVFE , 0xF01D +.set DMACLRTC , 0xF01E +.set DMA1TARPL , 0xF083 +.set DMA1TARPH , 0xF085 +.set DMA0TARPH , 0xF086 +.set DMA0TARPL , 0xF087 +.set DMA0BYCH , 0xF098 +.set DMA1BYCH , 0xF099 + +/* DMA UNIT REGISTERS -- SLOT 0 ADDRESSES */ +.set DMA0TARDOS , 0x0000 +.set DMA0BYCDOS , 0x0001 +.set DMA1TARDOS , 0x0002 +.set DMA1BYCDOS , 0x0003 +.set DMACMD1DOS , 0x0008 +.set DMASTSDOS , 0x0008 +.set DMASRRDOS , 0x0009 +.set DMAMSKDOS , 0x000A +.set DMAMOD1DOS , 0x000B +.set DMACLRBPDOS , 0x000C +.set DMACLRDOS , 0x000D +.set DMACLRMSKDOS , 0x000E +.set DMAGRPMSKDOS , 0x000F +.set DMA1TARPLDOS , 0x0083 +.set DMA0TARPLDOS , 0x0087 + +/* A20GATE AND FAST CPU RESET -- SLOT 15 ADDRESS */ +.set PORT92 , 0xF092 +/* A20GATE AND FAST CPU RESET -- SLOT 0 ADDRESS */ +.set PORT92DOS , 0x0092 diff --git a/c/src/lib/libbsp/i386/ts_386ex/start/Makefile.in b/c/src/lib/libbsp/i386/ts_386ex/start/Makefile.in new file mode 100644 index 0000000000..313955a579 --- /dev/null +++ b/c/src/lib/libbsp/i386/ts_386ex/start/Makefile.in @@ -0,0 +1,72 @@ +# +# $Id$ +# + +@SET_MAKE@ +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +top_builddir = ../../../../../../.. +subdir = c/src/lib/libbsp/i386/ts_386ex/start + +INSTALL = @INSTALL@ + +RTEMS_ROOT = $(top_srcdir)/@RTEMS_TOPdir@ +PROJECT_ROOT = @PROJECT_ROOT@ + +VPATH = @srcdir@ + +RTEMS_GAS_CODE16 = @RTEMS_GAS_CODE16@ + +PGMS=${ARCH}/start.o + +# C source names, if any, go here -- minus the .c +C_PIECES= +C_FILES=$(C_PIECES:%=%.c) +C_O_FILES=$(C_PIECES:%=${ARCH}/%.o) + +H_FILES= + +# Assembly source names, if any, go here -- minus the .S +S_PIECES=start +S_FILES=$(S_PIECES:%=%.S) +S_O_FILES=$(S_FILES:%.S=${ARCH}/%.o) + +SRCS=$(C_FILES) $(H_FILES) $(S_FILES) +OBJS=$(C_O_FILES) $(S_O_FILES) + +include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg +include $(RTEMS_ROOT)/make/leaf.cfg + +# +# (OPTIONAL) Add local stuff here using += +# + +ifeq ($(RTEMS_GAS_CODE16),yes) +CPPFLAGS += -DNEW_GAS +endif + +CFLAGS += + +LD_PATHS += +LD_LIBS += +LDFLAGS += + +# +# Add your list of files to delete here. The config files +# already know how to delete some stuff, so you may want +# to just run 'make clean' first to see what gets missed. +# 'make clobber' already includes 'make clean' +# + +CLEAN_ADDITIONS += +CLOBBER_ADDITIONS += + +all: ${ARCH} $(SRCS) $(OBJS) $(PGM) + $(INSTALL_VARIANT) -m 555 ${PGMS} ${PROJECT_RELEASE}/lib + +# Install the program(s), appending _g or _p as appropriate. +# for include files, just use $(INSTALL_CHANGE) + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status diff --git a/c/src/lib/libbsp/i386/ts_386ex/start/macros.inc b/c/src/lib/libbsp/i386/ts_386ex/start/macros.inc new file mode 100644 index 0000000000..b3814479a2 --- /dev/null +++ b/c/src/lib/libbsp/i386/ts_386ex/start/macros.inc @@ -0,0 +1,115 @@ +/* macros.inc + * + * This file assists the board independent startup code + * by initializing the chip-select channels to + * reflect the proper memory configuration. + * + * NOTE: No stack has been established when this routine + * is invoked. It returns to start.s through ldsegs + * + * Submitted by: + * + * Erik Ivanenko + * University of Toronto + * erik.ivanenko@utoronto.ca + * + * 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$ + */ + +.set GDT_CODE_PTR , 0x08 +.set GDT_DATA_PTR , 0x10 + +.set BOARD_SELECT , 0x301 +.set BOARD_DATA , 0x302 +.set BOARD_LATCH , 0x303 + + +#define SetExRegByte(_register,_value) \ + movb $ ## _value, al; \ + movw $ ## _register, dx; \ + outb al, dx + +#define SetExRegWord(_register,_value) \ + movw $ ## _value, ax; \ + movw $ ## _register, dx ; \ + outw ax, dx + + +#define DESC2(lim_0_15, bas_0_15, bas_16_23, access, gran, bas_24_31) \ + .word lim_0_15 ; \ + .word bas_0_15 ; \ + .byte bas_16_23 ; \ + .byte access ; \ + .byte gran ; \ + .byte bas_24_31 + +#define DESC3( _base, _limit) \ +.word _limit ; \ +.long _base + +/* THE GET_ACCESS IS CHANGED FROM 8E TO 9E */ + +#define INTERRUPT_GATE( _vector ) \ + .word _vector ; \ + .word GDT_CODE_PTR ; \ + .byte 0x0 ; \ + .byte 0x8E ; \ + .word 0x0 + +#define rLOAD_INDEX( _selector, _segment_register) \ + movl _selector , _segment_register ; \ + addb al, ( eax ) + +#define rLOAD_SEGMENT( _reg, _segment_register) \ + mov _reg , _segment_register ; \ + +/* #define rLOAD_SEGMENT( _reg, _segment_register) \ + .code16 ; \ + mov _reg , _segment_register ; \ + .code32 +*/ +#define pLOAD_SEGMENT( _selector, _segment_register) \ + movl $ ## _selector , eax ; .code16 ; \ + mov ax, _segment_register ; .code32 + +/* #define MOVE_WORD( _immed32, _reg ) \ + data16 ; \ + movl _immed32, _reg +*/ + +#define MOVE_WORD( _immed32, _reg ) \ + movw _immed32, _reg + +/* #define MOVE_IMMED_WORD( _immed32, _reg ) \ + data16 ; \ + mov $ ## _immed32, _reg + +#define CS_OFF( _cs_symbol, _reg ) \ + data16 ; \ + mov _cs_symbol, _reg ; \ + data16 ;\ + andl $0x000ffff, _reg + +#define _16_NOPS \ + nop ; \ + nop ; \ + nop ; \ + nop ; \ + nop ; \ + nop ; \ + nop ; \ + nop ; \ + nop ; \ + nop ; \ + nop ; \ + nop ; \ + nop ; \ + nop ; \ + nop ; \ + nop ; +*/ + diff --git a/c/src/lib/libbsp/i386/ts_386ex/start/start.S b/c/src/lib/libbsp/i386/ts_386ex/start/start.S new file mode 100644 index 0000000000..7a3c8509c1 --- /dev/null +++ b/c/src/lib/libbsp/i386/ts_386ex/start/start.S @@ -0,0 +1,501 @@ +/* + * This file is the main boot and configuration file for the TS-1325. It is + * solely responsible for initializing the internal register set to reflect + * the proper board configuration. This version is modified from the i386ex + * BSP startup: + * + * 1) 1 MB RAM @ 0x0100000 + * 2) 1 MB RAM @ 0x0 but with standard DOS memory usage. + * 3) Timer0 used as RTEMS clock ticker, 1 msec tick rate. + * 4) READY# is generated by CPU + * + * The file describes the ".initial" section, which contains: + * 1) device configuration code + * 2) interrupt descriptor table + * 3) global descriptor table + * 4) and initial boot code + * + * Modified by: + * + * Tony Ambardar + * University of British Columbia + * tonya@ece.ubc.ca + * + * 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 "asm.h" +#include "macros.inc" +#include "80386ex.inc" + +#include "ts_1325.inc" /* controls for LED and button */ + +/* + * NEW_GAS Needed for binutils 2.9.1.0.7 and higher + */ + + EXTERN (boot_card) /* exits to bspstart */ + EXTERN (_DOS_seg_base) /* defined in startup/linkcmds */ + EXTERN (Clock_exit) + + PUBLIC (Interrupt_descriptor_table) + PUBLIC ( SYM(IDTR) ) + PUBLIC (_Global_descriptor_table) + PUBLIC ( SYM(GDTR) ) + + PUBLIC( SYM(_init_i386ex) ) + + + .section .initial + +/* + * Enable access to peripheral register at expanded I/O addresses + */ +SYM(_init_i386ex): + .code16 +/* + LED_GREEN + WAIT_BUTTON +*/ +# cli Move this up for now for debug. + movw $0x8000 , ax + outb al , $REMAPCFGH + xchg al , ah + outb al , $REMAPCFGL + outw ax , $REMAPCFG ; +/* + LED_OFF + WAIT_BUTTON +*/ +/* + * Configure operation of the A20 Address Line + */ +SYM(A20): + movw $PORT92 , dx + + inb dx , al # clear A20 port reset + andb $0xfe , al # b0 Fast Reset(0)=disabled,(1)=reset triggered + orb $0x02 , al # Bit 1 Fast A20 = 0 (always 0) else enabled. + outb al , dx +/* + LED_YELLOW + WAIT_BUTTON +*/ +SYM(Watchdog): + movw $WDTSTATUS , dx # address the WDT status port + inb dx , al # get the WDT status + orb $0x01 , al # set the CLKDIS bit + outb al , dx # disable the clock to the WDT +/* + LED_GREEN + WAIT_BUTTON +*/ +/* + * Initialize Refresh Control Unit for: + * Refresh Address = 0x0000 + + * Refresh gate between rows is 20.0 (???) uSec + * Using a CLK2 frequency of 50Mhz ( 25Mhz CPU ) + * The refresh unit is enabled + * The refresh pin is not used. + * + * Different TS units might have different refresh intervals, so + * comment out. Will be set up anyway after booting to DOS. + */ + +/* +SYM(InitRCU): + SetExRegWord( RFSCIR , 0x1F4) # refresh interval 500 + SetExRegWord( RFSBAD , 0x0) # base address + SetExRegWord( RFSADD , 0x0) # address register + SetExRegWord( RFSCON , 0x8000) # enable bit +*/ + +/* + LED_OFF + WAIT_BUTTON +*/ +/* + * Initialize clock and power mgmt unit for: + * Clock Frequency = 50 Mhz + * Prescaled clock output = 1 Mhz + * Normal halt instructions + * + * NOTE: Hope this doesn't change the COMCLK frequency + */ + +SYM(InitClk): + SetExRegByte( PWRCON, 0x0 ) + SetExRegWord( CLKPRS, 0x17) # 0x13 for 1.19318 MHz. 0x17 for 1MHz. + +/************************************************************** + * Initialize the Pin Configurations + *************************************************************/ +/* + LED_YELLOW + WAIT_BUTTON +*/ +/* + * Initialize I/O port 1 for: + * PIN 0 = 0, Inport for external push-button switch + * PIN 1 = 1, RTS0# to package pin + * PIN 2 = 1, DTR0# to package pin + * PIN 3 = 1, DSR0# to package pin + * PIN 4 = 0, Inport ??? + * PIN 5 = 0, Outport (Green LED, 1 = ON) + * PIN 6 = 0, Outport (Red LED, 1 = OFF) + * PIN 7 = 0, Inport ??? + */ + +SYM(InitPort1): + SetExRegByte( P1LTC , 0xd1 ) + SetExRegByte( P1DIR , 0x91) + SetExRegByte( P1CFG , 0x0e) +/* + LED_GREEN + WAIT_BUTTON +*/ +/* + * Initialize I/O port 2 for: + * PIN 0 = 0, Outport ??? + * PIN 1 = 0, Outport ??? + * PIN 2 = 0, Outport ??? + * PIN 3 = 0, Outport ??? + * PIN 4 = 0, Outport ??? + * PIN 5 = 1, Int. periph, RXD0 + * PIN 6 = 1, Int. periph, TXD0 + * PIN 7 = 0, Outport ??? + */ + +SYM(InitPort2): + SetExRegByte( P2LTC , 0x1f ) + SetExRegByte( P2DIR , 0x00 ) + SetExRegByte( P2CFG , 0x60) +/* + LED_OFF + WAIT_BUTTON +*/ +/* + * Initialize I/O port 3 P3CFG + * PIN 0 = 1, Int. periph, TMROUT0 + * PIN 1 = 1, Int. periph, TMROUT1 + * PIN 2 = 1, Int. periph, INT0 (IR1) + * PIN 3 = 1, Int. periph, INT1 (IR5) + * PIN 4 = 1, Int. periph, INT2 (IR6) + * PIN 5 = 1, Int. periph, INT2 (IR7) + * PIN 6 = 0, Outport ??? + * PIN 7 = 1, Int. periph, COMCLK used for serial I/O + */ + +SYM(InitPort3): + SetExRegByte( P3LTC , 0x00 ) + SetExRegByte( P3DIR , 0xbf ) + SetExRegByte( P3CFG , 0xbf ) # can check TMROUT0 +/* + LED_YELLOW + WAIT_BUTTON +*/ +/* + * Initialize Peripheral Pin Configurations: + * PIN 0 = 1, Select RTS1# + * PIN 1 = 1, Select DTR1# + * PIN 2 = 1, Select TXD1# + * PIN 3 = 1, Select CTS1# + * PIN 4 = 1, CS5 + * PIN 5 = 1, Timer2 pins enabled + * PIN 6 = 0, Select CS6# + * PIN 7 = 0, Don't care + */ + +SYM(InitPeriph): + SetExRegByte( PINCFG , 0x3f) +/* + LED_GREEN + WAIT_BUTTON +*/ +/* + * Initialize the Asynchronous Serial Ports: + * BIT 7 = 1, Internal SIO1 modem signals + * BIT 6 = 1, Internal SIO0 modem signals + * BIT 2 = 0, PSCLK for SSIO clock + * BIT 1 = 1, SERCLK for SIO1 clock + * BIT 0 = 1, SERCLK for SIO0 clock + */ + +SYM(InitSIO): + SetExRegByte( SIOCFG, 0x00 ) # COMCLK -> baud-rate generator + # modem signals -> package pins + SetExRegByte( LCR0, 0x80 ) # latch DLL0, DLH0 + SetExRegByte( DLL0, 0x01 ) # 0x0C sets to 9600 baud 0x6 = 19.2K + SetExRegByte( DLH0, 0x00 ) # 0x4 is 28.8K baud, 0x1 is 115K baud + SetExRegByte( LCR0, 0x03 ) # enable r/w buffers, IER0 accessible + # mode 8-n-1 + SetExRegByte( IER0, 0x00 ) # no generated interrupts + + SetExRegByte( LCR1, 0x80 ) # latch DLL0, DLH0 + SetExRegByte( DLL1, 0x01 ) # 0x0C set to 9600 baud, 0x6 = 19.2K + SetExRegByte( DLH1, 0x00 ) # 0x4 is 28.8K baud + SetExRegByte( LCR1, 0x03 ) # enable r/w buffers, IER1 accessible + # reg 8-n-1 + SetExRegByte( IER1, 0x00 ) # no generated intrrupts +/* + LED_OFF + WAIT_BUTTON +*/ +SYM(InitMCR): + SetExRegByte( MCR0, 0x03 ) # standard mode, RTS,DTR activated + SetExRegByte( MCR1, 0x03 ) # standard mode, RTS,DTR activated + +/* + * Initialize Timer for: + * BIT 7 = 1, Timer clocks disabled + * BIT 6 = 0, Reserved + * BIT 5 = 1, TMRCLK2 instead of Vcc to Gate2 + * BIT 4 = 0, PSCLK to CLK2 + * BIT 3 = 1, TMRCLK1 instead of Vcc to Gate1 + * BIT 2 = 0, PSCLK to Gate1 + * BIT 1 = 0, Vcc to Gate0 + * BIT 0 = 0, PSCLK to Gate0 + */ +/* + LED_YELLOW + WAIT_BUTTON +*/ +SYM(InitTimer): + SetExRegByte(TMRCFG , 0x80 ) # All counters disabled, Gates 0,1 + # and 2 are set to Vcc + + SetExRegByte(TMRCON , 0x34 ) # prepare to write counter 0 LSB,MSB + SetExRegByte(TMR0 , 0x00 ) # sfa + SetExRegByte(TMR0 , 0x00 ) # sfa + + + SetExRegByte(TMRCON , 0x70 ) # mode 0 disables on Gate= Vcc + SetExRegByte(TMR1 , 0x00 ) # sfa + SetExRegByte(TMR1 , 0x00 ) # sfa + + SetExRegByte(TMRCON , 0xB0 ) # mode 0 disables on gate =Vcc + SetExRegByte(TMR2 , 0x00 ) # + SetExRegByte(TMR2 , 0x00 ) # + +/* + LED_GREEN + WAIT_BUTTON +*/ +/* + * Initialize the DMACFG register for: + * BIT 7 = 1 , Disable DACK#1 + * BITs 6:4 = 100, TMROUT2 connected to DRQ1 + * BIT 3 = 1 , Disable DACK0# + * BIT 2:0 = 000, Pin is connected to DRQ0 + * + * NOTE: not 100% sure of this... + */ + + SetExRegByte(DMACFG , 0xC0 ) + SetExRegByte(DMACMD1, 0x00 ) # disable both DMA channels + SetExRegByte(DMAMOD1, 0x40 ) # DMA0 single transer mode +/* + LED_OFF + WAIT_BUTTON +*/ +/* + * Initialize the INTCFG register for: + * BIT 7 = 0, 8259 cascade disabled + * BIT 3 = 0, SLAVE IR6 connected to Vss + * BIT 2 = 0, SLAVE IR5 connected to Vss + * BIT 1 = 0, SLAVE IR1 connected to SSIOINT + * BIT 0 = 0, SLAVE IR0 connected to Vss + * + * NOTE: not 100% sure of this either... Why IR5 active? + */ + +SYM(InitInt): + + cli # ! +/* + LED_YELLOW + WAIT_BUTTON +*/ + SetExRegByte(ICW1S , 0x11 ) # EDGE TRIGGERED + SetExRegByte(ICW2S , 0x28 ) # Slave base vector after Master + SetExRegByte(ICW3S , 0x02 ) # slave cascaded to IR2 on master + SetExRegByte(ICW4S , 0x01 ) # fully nested mode, no EOI + + SetExRegByte(ICW1M , 0x11 ) # edge triggered + SetExRegByte(ICW2M , 0x20 ) # base vector starts at byte 32 + SetExRegByte(ICW3M , 0x04) # internal slave cascaded from master IR2 + SetExRegByte(ICW4M , 0x01 ) # idem + + SetExRegByte(OCW1M , 0xfb ) # mask master IRQs, but not IR2 (cascade) + SetExRegByte(OCW1S , 0xff ) # mask all slave IRQs + SetExRegByte(INTCFG , 0x00 ) # slave IRs -> Vss or SSIOINT + +/* The i8259s_cache (IRQ mask) location is in BSS, which is zeroed later! + * So to initialize the cache we should do the following command after + * the BSS is zeroed, and in 32-bit protected mode. + * + * movw $0xFFFB, SYM(i8259s_cache) + * + */ + +/* + NOTE: not sure about this so comment out... + +SYM(SetCS4): + SetExRegWord(CS4ADL , 0x702) #Configure chip select 4 + SetExRegWord(CS4ADH , 0x00) + SetExRegWord(CS4MSKH, 0x03F) + SetExRegWord(CS4MSKL, 0xFC01) +*/ +/* + LED_GREEN + WAIT_BUTTON +*/ +/***************************** + * Load the Global Descriptor + * Table Register + ****************************/ + + movl $SYM(GDTR), eax + andl $0xFFFF, eax + +#ifdef NEW_GAS + addr32 + data32 +#endif + + lgdt (eax) # location of GDT in segment + +/* + NOTE: not sure about this either so comment out for now... +SYM(SetUCS): + SetExRegWord(UCSADL, 0xC503) # values taken from TS-1325 memory + SetExRegWord(UCSADH, 0x000D) + SetExRegWord(UCSMSKH, 0x0000) + SetExRegWord(UCSMSKL, 0x3C01) # configure upper chip select +*/ +/* + LED_OFF + WAIT_BUTTON +*/ +/*************************** + * Switch to Protected Mode + ***************************/ + mov cr0, eax + orw $0x1, ax + mov eax, cr0 + +/************************** + * Flush prefetch queue, + * and load CS selector + *********************/ +/* + LED_YELLOW + WAIT_BUTTON +*/ + ljmpl $ GDT_CODE_PTR , $ SYM(_load_segment_registers) # sets the code selector + +/* + * Load the segment registers + */ +SYM(_load_segment_registers): + .code32 +/* + LED_GREEN + WAIT_BUTTON +*/ + pLOAD_SEGMENT( GDT_DATA_PTR, fs) + pLOAD_SEGMENT( GDT_DATA_PTR, gs) + pLOAD_SEGMENT( GDT_DATA_PTR, ss) + pLOAD_SEGMENT( GDT_DATA_PTR, ds) + pLOAD_SEGMENT( GDT_DATA_PTR, es) + +/* + * Set up the stack + */ +/* + LED_OFF + WAIT_BUTTON +*/ +SYM(lidtr): + lidt SYM(IDTR) +/* + LED_YELLOW + WAIT_BUTTON +*/ +SYM (_establish_stack): + movl $_ebss, eax # stack starts right after bss + movl $stack_origin, esp # this is the high starting address + movl $stack_origin, ebp +/* + LED_GREEN + WAIT_BUTTON +*/ +/* + * Zero out the BSS segment + */ +SYM (zero_bss): + cld # make direction flag count up + movl $ SYM (_ebss),ecx # find end of .bss + movl $ SYM (_bss_start),edi # edi = beginning of .bss + subl edi,ecx # ecx = size of .bss in bytes + shrl ecx # size of .bss in longs + shrl ecx + xorl eax,eax # value to clear out memory + repne # while ecx != 0 + stosl # clear a long in the bss +/* + * Now we can initialize the IRQ mask in i8259s_cache + */ + movw $0xFFFB, SYM(i8259s_cache) +/* + LED_YELLOW # Indicate ready to run + WAIT_BUTTON +*/ + LED_GREEN # Indicate RTEMS running! + +/* + * Transfer control to User's Board Support Package + */ + pushl $0 # environp + pushl $0 # argv + pushl $0 # argc + call SYM(boot_card) + addl $12,esp + + LED_RED # Indicate RTEMS exited +/* + WAIT_BUTTON +*/ + cli # stops interrupts after hlt! + hlt # shutdown + + + .balign 4 # align tables to 4 byte boundary + +SYM(IDTR): DESC3( SYM(Interrupt_descriptor_table), 0x07ff ); + +SYM(Interrupt_descriptor_table): /* Now in data section */ + .rept 256 + .word 0,0,0,0 + .endr + + +/* + * Use the first (null) entry in the the GDT as a self-pointer for the GDTR. + * (looks like a common trick) + */ + +SYM (_Global_descriptor_table): +SYM(GDTR): DESC3( GDTR, 0x17 ); # one less than the size + .word 0 # padding to DESC2 size +SYM(GDT_CODE): DESC2(0xffff,0,0x0,0x9B,0xDF,0x00); +SYM(GDT_DATA): DESC2(0xffff,0,0x0,0x92,0xDF,0x00); # was CF +SYM(GDT_END): + +END diff --git a/c/src/lib/libbsp/i386/ts_386ex/start/ts_1325.inc b/c/src/lib/libbsp/i386/ts_386ex/start/ts_1325.inc new file mode 100644 index 0000000000..e10999abc0 --- /dev/null +++ b/c/src/lib/libbsp/i386/ts_386ex/start/ts_1325.inc @@ -0,0 +1,50 @@ +/* + These are just some useful macros that control the TS-1325's + LEDs and push-button switch. Useful for debugging. + + NOTE: This *must* be 16-bit compatible code to work in start.s + + Tony Ambardar +*/ + + .macro LED_OFF + movw $P1LTC, dx + inb dx, al + orb $0b01000000, al + andb $0b11011111, al + outb al, dx + .endm + + .macro LED_GREEN + movw $P1LTC, dx + inb dx, al + orb $0b01100000, al + outb al, dx + .endm + + .macro LED_YELLOW + movw $P1LTC, dx + inb dx, al + orb $0b00100000, al + andb $0b10111111, al + outb al, dx + .endm + + .macro LED_RED + movw $P1LTC, dx + inb dx, al + andb $0b10011111, al + outb al, dx + .endm + + .macro WAIT_BUTTON # Wait till the button is pressed for a bit. + movw $P1PIN, dx # ~25-30 cycles per loop, 25MHz -> 1 sec. + movl $300000,ecx # "Timer" count determines how long. +0: inb dx, al + andb $0b00000001,al + jnz 0b # Button pressed? + decl ecx + jnz 0b # CX count expired? + .endm + + diff --git a/c/src/lib/libbsp/i386/ts_386ex/startup/Makefile.in b/c/src/lib/libbsp/i386/ts_386ex/startup/Makefile.in new file mode 100644 index 0000000000..89e2fce951 --- /dev/null +++ b/c/src/lib/libbsp/i386/ts_386ex/startup/Makefile.in @@ -0,0 +1,79 @@ +# +# $Id$ +# + +@SET_MAKE@ +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +top_builddir = ../../../../../../.. +subdir = c/src/lib/libbsp/i386/ts_386ex/startup + +INSTALL = @INSTALL@ + +RTEMS_ROOT = $(top_srcdir)/@RTEMS_TOPdir@ +PROJECT_ROOT = @PROJECT_ROOT@ + +VPATH = @srcdir@:@srcdir@/../../../shared:@srcdir@/../../shared/comm:@srcdir@/../../shared/irq:@srcdir@/../../shared/io + +PGM=${ARCH}/startup.rel + +# C source names, if any, go here -- minus the .c +C_PIECES=bspclean bsplibc bsppost bspstart main sbrk irq irq_init i386-stub-glue uart i386-stub + +C_FILES=$(C_PIECES:%=%.c) +C_O_FILES=$(C_PIECES:%=${ARCH}/%.o) + +H_FILES= + +# Assembly source names, if any, go here -- minus the .S +# removed initcsu piece, ldsegs piece and flush +S_PIECES=irq_asm +S_FILES=$(S_PIECES:%=%.S) +S_O_FILES=$(S_FILES:%.S=${ARCH}/%.o) + +SRCS=$(srcdir)/linkcmds $(C_FILES) $(CC_FILES) $(H_FILES) $(S_FILES) +OBJS=$(C_O_FILES) $(CC_O_FILES) $(S_O_FILES) + +include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg +include $(RTEMS_ROOT)/make/leaf.cfg + +# +# (OPTIONAL) Add local stuff here using += +# + +#DEFINES += -DPRINTON + +DEFINES += -I$(srcdir) +CPPFLAGS += +CFLAGS += + +LD_PATHS += +LD_LIBS += +LDFLAGS += + +# +# Add your list of files to delete here. The config files +# already know how to delete some stuff, so you may want +# to just run 'make clean' first to see what gets missed. +# 'make clobber' already includes 'make clean' +# + +CLEAN_ADDITIONS += +CLOBBER_ADDITIONS += + +preinstall: + $(INSTALL_CHANGE) ${IMPORT_SRC} . + +# ${CP} ${IMPORT_SRC} . + +${PGM}: ${SRCS} ${OBJS} + $(make-rel) +all: ${ARCH} preinstall $(SRCS) $(PGM) + $(INSTALL_CHANGE) $(srcdir)/linkcmds ${PROJECT_RELEASE}/lib + +# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile +install: all + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status diff --git a/c/src/lib/libbsp/i386/ts_386ex/startup/README b/c/src/lib/libbsp/i386/ts_386ex/startup/README new file mode 100644 index 0000000000..17fde76a91 --- /dev/null +++ b/c/src/lib/libbsp/i386/ts_386ex/startup/README @@ -0,0 +1,17 @@ +# +# $Id$ +# + + +The requirements for this BSP are only that the GAS used supports the +.code16 directive. The GAS released with any GCC version 2.8.0 or better +is required. The BSP was built with an egcs snapshot pre-1.0.2 and +post-1.0.1. However, any egcs should work. + + +The only "real" differences are in bspstart.c, where the initialization now +configures all available RAM, (after setting up the Workspaces) as heap. +The location of the stack was changed so that the heap was not trapped +between low memory and the stack; the stack comes before the heap. + + diff --git a/c/src/lib/libbsp/i386/ts_386ex/startup/bspstart.c b/c/src/lib/libbsp/i386/ts_386ex/startup/bspstart.c new file mode 100644 index 0000000000..c0e92617e8 --- /dev/null +++ b/c/src/lib/libbsp/i386/ts_386ex/startup/bspstart.c @@ -0,0 +1,161 @@ +/* + * 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-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * 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. + * + * Ported to the i386ex and submitted by: + * + * Erik Ivanenko + * University of Toronto + * erik.ivanenko@utoronto.ca + * + * $Id$ + */ + +void bsp_clean_up(void); + +#include +#include + +#include + +/* + * 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; + +/* + * Tells us where to put the workspace in case remote debugger is present. + */ + +extern rtems_unsigned32 rdb_start; + +/* + * 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) +{ + extern int heap_bottom; + rtems_unsigned32 heap_start; + rtems_unsigned32 heap_size; + + heap_start = (rtems_unsigned32) &heap_bottom; + if (heap_start & (CPU_ALIGNMENT-1)) + heap_start = (heap_start + CPU_ALIGNMENT) & ~(CPU_ALIGNMENT-1); + + heap_size = BSP_Configuration.work_space_start -(void *) heap_start ; + heap_size &= 0xfffffff0; /* keep it as a multiple of 16 bytes */ + + heap_size &= 0xfffffff0; /* keep it as a multiple of 16 bytes */ + bsp_libc_init((void *) heap_start, heap_size, 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 ) +{ + /* + * we do not use the pretasking_hook. + */ + + Cpu_table.pretasking_hook = bsp_pretasking_hook; /* init libc, etc. */ + Cpu_table.postdriver_hook = bsp_postdriver_hook; + Cpu_table.interrupt_table_segment = get_ds(); + Cpu_table.interrupt_table_offset = (void *)Interrupt_descriptor_table; + Cpu_table.interrupt_stack_size = 8192; + /* +#if defined(RTEMS_POSIX_API) + BSP_Configuration.work_space_size *= 3; +#endif + */ + BSP_Configuration.work_space_start = (void *) + RAM_END - BSP_Configuration.work_space_size; + + /* + * Account for the console's resources + */ + console_reserve_resources( &BSP_Configuration ); + + /* + * Init rtems_interrupt_management + */ + rtems_irq_mngt_init(); + + /* + * Init rtems exceptions management + */ + rtems_exception_init_mngt(); + + /* + * The following information is very useful when debugging. + */ + +#ifdef BSP_DEBUG + printk( "RAM_START = 0x%x\nRAM_END = 0x%x\n", RAM_START, RAM_END ); + printk( "work_space_start = 0x%x\n", + BSP_Configuration.work_space_start ); + printk( "work_space_size = 0x%x\n", + BSP_Configuration.work_space_size ); + printk( "maximum_extensions = 0x%x\n", + BSP_Configuration.maximum_extensions ); + printk( "microseconds_per_tick = 0x%x\n", + BSP_Configuration.microseconds_per_tick ); + printk( "ticks_per_timeslice = 0x%x\n", + BSP_Configuration.ticks_per_timeslice ); + printk( "maximum_devices = 0x%x\n", + BSP_Configuration.maximum_devices ); + printk( "number_of_device_drivers = 0x%x\n", + BSP_Configuration.number_of_device_drivers ); + printk( "Device_driver_table = 0x%x\n", + BSP_Configuration.Device_driver_table ); + + /* printk( "_heap_size = 0x%x\n", _heap_size ); + printk( "_stack_size = 0x%x\n", _stack_size ); */ +#endif +} + +void bsp_clean_up(void) { + printk("bsp_cleanup called\n"); +} + diff --git a/c/src/lib/libbsp/i386/ts_386ex/startup/linkcmds b/c/src/lib/libbsp/i386/ts_386ex/startup/linkcmds new file mode 100644 index 0000000000..99911126bb --- /dev/null +++ b/c/src/lib/libbsp/i386/ts_386ex/startup/linkcmds @@ -0,0 +1,124 @@ +/* + * This file contains directives for the GNU linker which are specific + * to the Technologic Systems TS-1325 (i386ex) board. + * + * Copyright (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * 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 layout: + * + * 0x0008000 -> ... : initial section ( init 386ex, goto protected mode) + * ... -> ... : text section ( executable code ) + * ... -> 0x00A0000 : data section ( initialized storage ) + * 0x0100000 -> 0x0200000 : bss section, stack space, heap storage + */ + + ENTRY(_init_i386ex) ; +SECTIONS +{ + +/*************************************************************************** + * initial section: + * + * This section is the first in memory, preceding the text and data sections. + * It initializes the i386ex, sets up the gdt in RAM, loads the gdt, + * jumps to protected mode, loads the idt, zeros the bss section, sets up + * the stack and calls the rest of the RTEMS initialization. + ***************************************************************************/ + + _DOS_ld_addr = 0x0008000 ; + + .initial _DOS_ld_addr : + { + *(.initial); + } + +/*************************************************************************** + * text section: + * + * Nobody here but us opcodes. + ***************************************************************************/ + + .text BLOCK(0x10) : + { + CREATE_OBJECT_SYMBOLS + 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__ = .; + . = ALIGN (4) ; + __DTOR_LIST__ = .; + LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2) + *(.dtors) + LONG(0) + __DTOR_END__ = .; + _rodata_start = . ; + *(.rodata) + *(.gnu.linkonce.r*) + _erodata = ALIGN( 0x10 ) ; + _etext = ALIGN( 0x10 ); + _endtext = . ; + } + +/*************************************************************************** + * data section: + * + * This section defines the location of the data section in RAM. + ***************************************************************************/ + + .data BLOCK(0x10) : + { + _sdata = .; + *(.data); + _edata = .; + } + _data_size = _edata - _sdata ; + +/*************************************************************************** + * bss section: + * + * The bss section is the first section in extended RAM ( > 1MB). + ***************************************************************************/ + + .bss 0x100000 (NOLOAD) : + { + _bss_start = .; + *(.bss); + *(COMMON); + _ebss = ALIGN(0x10); + } + _bss_size = _ebss - _bss_start ; + +/*************************************************************************** + * General variables: + * + * The stack_size variable is customizable here. The heap is located directly + * after the stack in RAM. A routine within bspstart.c uses these variables + * to ensure that the heap used by RTEMS is as large as the RAM remaining + * after all workspace configurations are complete. + ***************************************************************************/ + + stack_size = 0x8000 ; + stack_origin = _ebss + stack_size ; + heap_bottom = stack_origin + 4 ; + +} diff --git a/c/src/lib/libbsp/i386/ts_386ex/startup/setvec.c b/c/src/lib/libbsp/i386/ts_386ex/startup/setvec.c new file mode 100644 index 0000000000..9e7a0e758d --- /dev/null +++ b/c/src/lib/libbsp/i386/ts_386ex/startup/setvec.c @@ -0,0 +1,55 @@ +/* set_vector + * + * This routine installs an interrupt vector on the Force CPU-386. + * + * 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-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * 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 + +i386_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 */ +) +{ + i386_isr_entry previous_isr; + interrupt_gate_descriptor idt; + + if ( type ) + rtems_interrupt_catch( handler, vector, (rtems_isr_entry *) &previous_isr ); + else { + /* get the address of the old handler */ + + idt = Interrupt_descriptor_table[ vector ]; + + previous_isr = (i386_isr_entry) + ((idt.offset_16_31 << 16) | idt.offset_0_15); + + /* build the IDT entry */ + create_interrupt_gate_descriptor( &idt, handler ); + + /* install the IDT entry */ + Interrupt_descriptor_table[ vector ] = idt; + } + return previous_isr; +} + diff --git a/c/src/lib/libbsp/i386/ts_386ex/timer/Makefile.in b/c/src/lib/libbsp/i386/ts_386ex/timer/Makefile.in new file mode 100644 index 0000000000..729885a081 --- /dev/null +++ b/c/src/lib/libbsp/i386/ts_386ex/timer/Makefile.in @@ -0,0 +1,70 @@ +# +# $Id$ +# + +@SET_MAKE@ +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +top_builddir = ../../../../../../.. +subdir = c/src/lib/libbsp/i386/ts_386ex/timer + +INSTALL = @INSTALL@ + +RTEMS_ROOT = $(top_srcdir)/@RTEMS_TOPdir@ +PROJECT_ROOT = @PROJECT_ROOT@ + +VPATH = @srcdir@ + +PGM=${ARCH}/timer.rel + +# C source names, if any, go here -- minus the .c +C_PIECES=timer +C_FILES=$(C_PIECES:%=%.c) +C_O_FILES=$(C_PIECES:%=${ARCH}/%.o) + +H_FILES= + +# Assembly source names, if any, go here -- minus the .S +S_PIECES=timerisr +S_FILES=$(S_PIECES:%=%.S) +S_O_FILES=$(S_FILES:%.S=${ARCH}/%.o) + +SRCS=$(C_FILES) $(CC_FILES) $(H_FILES) $(S_FILES) +OBJS=$(C_O_FILES) $(CC_O_FILES) $(S_O_FILES) + +include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg +include $(RTEMS_ROOT)/make/leaf.cfg + +# +# (OPTIONAL) Add local stuff here using += +# + +DEFINES += +CPPFLAGS += +CFLAGS += + +LD_PATHS += +LD_LIBS += +LDFLAGS += + +# +# Add your list of files to delete here. The config files +# already know how to delete some stuff, so you may want +# to just run 'make clean' first to see what gets missed. +# 'make clobber' already includes 'make clean' +# + +CLEAN_ADDITIONS += +CLOBBER_ADDITIONS += + +${PGM}: ${SRCS} ${OBJS} + $(make-rel) + +all: ${ARCH} $(SRCS) $(PGM) + +# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile +install: all + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status diff --git a/c/src/lib/libbsp/i386/ts_386ex/timer/timer.c b/c/src/lib/libbsp/i386/ts_386ex/timer/timer.c new file mode 100644 index 0000000000..fbbe92e347 --- /dev/null +++ b/c/src/lib/libbsp/i386/ts_386ex/timer/timer.c @@ -0,0 +1,195 @@ +/* Timer_init() + * + * This routine initializes the timer on the FORCE CPU-386 board. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * NOTE: This routine will not work if the optimizer is enabled + * for some compilers. The multiple writes to the Z8036 + * may be optimized away. + * + * It is important that the timer start/stop overhead be + * determined when porting or modifying this code. + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * 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 + +volatile rtems_unsigned32 Ttimer_val; /* Updated from ISR!!! */ +rtems_boolean Timer_driver_Find_average_overhead; + +extern void timerisr(); + +/* + * Number of us per timer interrupt. Note: 1 us == 1 tick. + */ + +#define US_PER_ISR 250 + +void TimerOn(const rtems_raw_irq_connect_data* used) +{ + + Ttimer_val = 0; /* clear timer ISR count */ + + /* Select timer, stay in mode 0 */ + outport_byte (TIMER_MODE, TIMER_SEL0|TIMER_16BIT|TIMER_RATEGEN); + + /* Set to 250 usec interval */ + outport_byte (TIMER_CNTR0, US_PER_ISR & 0xFF ); + outport_byte (TIMER_CNTR0, (US_PER_ISR >> 8) & 0xFF ); + + /* Enable all timers */ + outport_byte (TIMER_CONFIG, 0x00); + + /* + * enable interrrupt at i8259 level + */ + BSP_irq_enable_at_i8259s(used->idtIndex - BSP_IRQ_VECTOR_BASE); +} + +static int TimerIsOn (const rtems_raw_irq_connect_data *used) +{ + return BSP_irq_enabled_at_i8259s(used->idtIndex - BSP_IRQ_VECTOR_BASE); +} + +void TimerOff(const rtems_raw_irq_connect_data* used) +{ + /* Disable all timers */ + outport_byte (TIMER_CONFIG, 0x80); + + /* + * disable interrrupt at i8259 level + */ + BSP_irq_disable_at_i8259s(used->idtIndex - BSP_IRQ_VECTOR_BASE); + /* reset timer mode to standard (DOS) value */ +} + +static rtems_raw_irq_connect_data timer_raw_irq_data = { + BSP_PERIODIC_TIMER + BSP_IRQ_VECTOR_BASE, + timerisr, + TimerOn, + TimerOff, + TimerIsOn +}; + +static rtems_raw_irq_connect_data old_raw_irq_data = { + BSP_PERIODIC_TIMER + BSP_IRQ_VECTOR_BASE, +}; + +void Timer_exit() +{ + if (!i386_delete_idt_entry(&timer_raw_irq_data)) { + printk("Timer_exit:Timer raw handler removal failed\n"); + rtems_fatal_error_occurred(1); + } +} + +void Timer_initialize(void) +{ + + static rtems_boolean First = TRUE; + + if (First) + { + First = FALSE; + + if (!i386_get_current_idt_entry (&old_raw_irq_data)) { + printk("Timer_initialize: failed to get old raw irq entry.\n"); + rtems_fatal_error_occurred(1); + } + + if (!i386_delete_idt_entry (&old_raw_irq_data)) { + printk("Timer_initialize: failed to delete old raw irq entry.\n"); + rtems_fatal_error_occurred(1); + } + + atexit(Timer_exit); /* Try not to hose the system at exit. */ + if (!i386_set_idt_entry (&timer_raw_irq_data)) { + printk("Timer_initialize: raw handler installation failed.\n"); + rtems_fatal_error_occurred(1); + } + } + + /* wait for ISR to be called at least once */ + Ttimer_val = 0; + while (Ttimer_val == 0) + continue; + Ttimer_val = 0; +} + + +#define AVG_OVERHEAD 3 /* It typically takes 3.0 microseconds */ + /* (3 ticks) to start/stop the timer. */ +#define LEAST_VALID 4 /* Don't trust a value lower than this */ + +int Read_timer(void) +{ + register rtems_unsigned32 clicks, total; + register rtems_unsigned8 lsb, msb; + + /* latch the count */ + outport_byte (TIMER_MODE, TIMER_SEL0|TIMER_LATCH ); + + /* read the count */ + inport_byte (TIMER_CNTR0, lsb ); + inport_byte (TIMER_CNTR0, msb ); + + /* + * Timer ISR increments Ttimer_val every US_PER_ISR clock ticks, + * where 1 tick == 1 us. Below, 'click' is in microseconds. + * + * This assumes the timer input clocks are sourced from the system's + * prescaled clock (PSCLK), which is set to be at 1MHz. + */ + clicks = (msb << 8) | lsb; + total = Ttimer_val * US_PER_ISR + (US_PER_ISR - clicks); + + if ( Timer_driver_Find_average_overhead == 1 ) + return total; /* in one microsecond units */ + else if ( total < LEAST_VALID ) + return 0; /* below timer resolution */ + else + return (total - AVG_OVERHEAD); +} + +rtems_status_code Empty_function( void ) +{ + return RTEMS_SUCCESSFUL; +} + +void Set_find_average_overhead( + rtems_boolean find_flag +) +{ + Timer_driver_Find_average_overhead = find_flag; +} + +/* + * Wait_X_ms: a delay loop used by the network driver... + */ + +#define SLOW_DOWN_IO 0x80 /* I/O port which does nothing */ +#define LOOP1MS 320 /* Just a guess.... */ + +void Wait_X_ms (unsigned timeToWait) +{ + unsigned i, j; + + for (j=0; j" + echo + exit 1 +fi + +for i in $* +do + OUTFILE=$(basename `echo $i | sed 's/\.[a-zA-Z0-9]*$//g'`.bin) + $OBJCOPY -O binary $i $OUTFILE +done + diff --git a/c/src/lib/libbsp/i386/ts_386ex/tools/dos_sup/loader.com b/c/src/lib/libbsp/i386/ts_386ex/tools/dos_sup/loader.com new file mode 100644 index 0000000000..945a7d2339 Binary files /dev/null and b/c/src/lib/libbsp/i386/ts_386ex/tools/dos_sup/loader.com differ diff --git a/c/src/lib/libbsp/i386/ts_386ex/tools/dos_sup/loader_hybrid_com.asm b/c/src/lib/libbsp/i386/ts_386ex/tools/dos_sup/loader_hybrid_com.asm new file mode 100644 index 0000000000..cd951ec8fd --- /dev/null +++ b/c/src/lib/libbsp/i386/ts_386ex/tools/dos_sup/loader_hybrid_com.asm @@ -0,0 +1,575 @@ +; loader_hybrid_com.asm +; +; This is a DOS command-line loader for RTEMS executables running on +; the Technologic Systems TS-1325 Embedded PC. +; +; It loads a DOS file given on the command line to the address `KernelBase', +; and then transfers control there. It uses DOS file I/O commands to read from +; the A: flash disk, and direct memory access to read from the C: ramdisk. +; +; Copying uses protected flat mode, so kernelbase could be above 1MB. +; It does not initialize protected mode before transferring control +; to the RTEMS executable image. +; +; Compile with: nasm -o loader.com loader_hybrid_com.asm +; +; Tony Ambardar (c) 1999 +; E.C.E. Department +; University of British Columbia + +%include "ts1325.inc" ; Some useful LED and button macros + +; IMPORTANT: [org xxx] MUST be the same as RelocAddr below. + +[org E000h] +[bits 16] + +; Only these three definitions may need to change + +KernelBase equ 08000h ; Where (32-bit) to locate and run RTEMS executable + +RelocSeg equ 9000h ; Segment to relocate code. +RelocAddr equ 0E000h ; Address to relocate code, same as "org" above + +; Next three used in GDT + +RelocBase equ RelocSeg*16 +Reloc15 equ RelocBase & 0FFFFh +Reloc23 equ RelocBase / 10000h + +Buffer equ RelocAddr+400h ; In same segment as RelocSeg +BuffSiz equ 200h ; Size of disk read + copy + +StackSeg equ RelocSeg +StackSiz equ 40h +StackAddr equ Buffer+BuffSiz+StackSiz + +; Used to jump to kernel in real mode + +KernelAddr equ KernelBase & 0FFFFh +KernelSeg equ (KernelBase - KernelAddr) / 16 + +; Used to load from the ramdisk + +Extended equ 100000h ; Start of extended memory / C: ramdisk +OffsetBPB equ 0Bh ; Start of BIOS param block in bootsector + +; Command-line parameters + +ParamLen equ 80h ; Byte length of command line params +ParamStr equ 82h ; Start of param string + +; The ORG address above means pre-relocation addresses are wrong. The +; following macro fixes these up. + +%define PRE_RELOC_ADDR(addr) (addr-CodeStart+100h) + +CodeStart: + +mov dx, PRE_RELOC_ADDR(Greet) +mov ah, 9h +int 21h + +mov ax, 0b021h ; Exit to DOS if push-button switch pressed +int 15h +and al, 01h ; Bit 0 == 0 if button pressed +jz ButtonExit + +xor cx, cx +mov cl, [ParamLen] ; See if there is a command line arg +jcxz NameError + +dec cx ; Nix leading space. Is this standard? +cmp cx, 12 ; Limit to 12 chars: e.g. ABCDEFGH.IJK +jg NameError + ; Damn. Should make sure of no ':' or '\' chars too. + +; Required by "relocated" [org] statement above + +mov di, PRE_RELOC_ADDR(FName) +mov si, ParamStr +repne +movsb ; Copy command line arg + +; Make sure no ':' in filename. This forces using the default dir. + +mov di, PRE_RELOC_ADDR(FName) +mov al, ':' +mov cx, 12 +repne +scasb +je NameError + +jmp Relocate + +ButtonExit: +mov dx, PRE_RELOC_ADDR(Button) +jmp short DosPrint + +NameError: +mov dx, PRE_RELOC_ADDR(FError) +jmp short DosPrint + +DosError: ; Only call this AFTER relocation +mov dx, RError + +DosPrint: +mov ah, 9h +int 21h + +DosExit: +mov ax, 04C00h ; DOS Function: Exit program +int 21h ; Call DOS. Terminate Program + +Relocate: ; Move this code down to RelocAddr + +cld +mov ax, RelocSeg +mov es, ax ; Set destination = RelocSeg:RelocAddr +mov di, RelocAddr +mov si, 100h ; Source is ds:0100h i.e. a COM file +mov cx, CodeEnd - CodeStart ; Size of all code + +repne +movsb + +; continue in copied code + +jmp RelocSeg:RelocAddr + (RelocStart - CodeStart) + +RelocStart: +cli +mov ax, StackSeg +mov ss, ax +mov sp, StackAddr +mov ax, cs +mov ds, ax +mov es, ax ; Setup segments and stack +sti + +mov ah, 19h +int 21h +mov [DDrive], al ; Save current default drive + +mov ax, 3d00h ; DOS Function: Open the file for reading +mov dx, FName ; Presume DS points at filename segment +int 21h +jc DosError + +GoodOpen: +mov [FHndl], ax ; Save file handle + +mov al, [DDrive] ; Check if loading from C: drive (ramdisk) +cmp al, 2 +je LoadRamdisk + +LoadDosdisk: + +; Here we are loading from A: drive. Use DOS calls to load the file into +; extended memory. Then copy from extended memory to `KernelBase'. This way +; we avoid overwriting DOS file I/O structures if reading directly into +; conventional (<640K) memory. + +mov edi, Extended ; Destination for code read @ 1 Meg + +ReadLoop: + +mov ah,3fh ; DOS Function: Read data from the file +mov bx, [FHndl] +mov dx, Buffer ; Address of data buffer +mov cx, BuffSiz ; Request BuffSiz bytes +int 21h +jc DosError + +GoodRead: + +cmp ax, cx ; EOF reached? AX = # bytes read +pushf + +add ax, 3 +shr ax, 2 ; Copy buffer by dwords, # = (ax + 3)/4 +movzx ecx, ax +mov esi, RelocBase + Buffer ; Source for copy, destination is in edi + +call CopyData32 ; Do protected-mode copy + +popf +je ReadLoop ; Still data left, so read next chunk + +mov esi, Extended ; Source for copy @ 1 Meg +mov ecx, edi ; Make count in dwords +sub ecx, esi +add ecx, 3 +shr ecx, 2 +mov edi, KernelBase ; Destination copy + +call CopyData32 ; Move code into conventional memory +jmp RunKernel + +LoadRamdisk: + +; Here we are loading from C: drive. Use protected mode to directly access +; the virtual disk sectors in extended memory and copy to `KernelBase'. +; This way we avoid using DOS file I/O calls, except for an `open' earlier +; which tells us the file exists. + +; Copy C: "bootsector" to buffer and save the BIOS parameter block + +mov esi, Extended +mov edi, RelocBase + Buffer ; Must be a 32-but address... +mov ecx, 80h +call CopyData32 + +mov si, Buffer + OffsetBPB +mov di, SavBPB +mov cx, EndBPB - SavBPB +repne +movsb + +; Calculate FAT, root dir, and data start addresses for the ramdisk + +xor eax, eax +mov ebx, eax +mov ecx, ebx + +mov ax, [ResSec] + +mov bl, [NumFAT] +imul bx, [SecFAT] + +mov cx, [NRoot] +shr cx, 4 ; 10h directory entries per sector + +add bx, ax +add cx, bx + +mov dx, [BpSect] +imul ax, dx +imul bx, dx +imul cx, dx + +add eax, Extended +add ebx, Extended +add ecx, Extended + +mov [BegFAT], eax +mov [BegRoot], ebx +mov [BegData], ecx + +; Convert the saved filename to format used in directory entry. Assume +; there's a `.' in it. Hopefully this won't haunt us later... + +mov di, FName ; Find the `.' +mov al, '.' +mov cx, 12 +repne +scasb + +mov bx, di ; di points to filename extension + +mov di, DirName +mov si, FName +mov cx, bx ; Make count +sub cx, si +dec cx +repne ; Copy initial part of filename +movsb + +mov di, bx ; Find the terminating zero +xor al,al +mov cx, 4 +repne +scasb + +mov cx, di ; Make count +sub cx, bx +dec cx +mov si, bx +mov di, DirName + 8 +repne ; Copy filename extension +movsb + +mov si, DirName ; Convert the stupid thing to upper case +mov di, si +mov cx, 11 + +Cvt2Upper: + +lodsb +cmp al, 'a' +jb NotLow +cmp al, 'z' +ja NotLow +xor al, 20h + +NotLow: + +stosb +loop Cvt2Upper + +; Now load in the root directory (temporarily) to find the first cluster +; of our file. Use KernelSeg:KernelAddr as temporary storage. + +mov esi, [BegRoot] +mov edi, KernelBase +xor ecx, ecx +mov cx, [NRoot] +shl cx, 3 ; Each root entry is 8 dwords +call CopyData32 + +mov dx, [NRoot] ; Max # of dir entries + +mov cx, KernelSeg ; Setup segment selector for comparison +mov es, cx +mov di, KernelAddr + +FindEntry: + +mov cx, 11 +mov si, DirName +push di +rep cmpsb +pop di +je GotEntry +add di, 20h ; Point to next dir entry +dec dx +jnz FindEntry + +int 3h ; Should never get here... + +GotEntry: + +mov eax, KernelBase ; Setup initial address for copy +mov [CurrDst], eax + +add di, 32 - 6 ; Load first cluster number +mov ax, [es:di] +mov cx, ds ; Fix `es' selector just in case +mov es, cx + +LoadKernel: + +call LoadCluster ; Load cluster `ax' to [CurrDst], update [CurrDst] + +call NextCluster ; Get next cluster number in ax + +cmp ax, 0FF8h ; Repeat until EOF +jb LoadKernel + +RunKernel: + +mov ax, KernelSeg ; Setup data segment and transfer control +mov ds, ax + +jmp KernelSeg:KernelAddr ; Huzzah!! + + +; Load cluster `ax' to [CurrDst], update [CurrDst] + +LoadCluster: + +push ax +sub ax, 2 ; Cluster numbers start at 2 +movzx eax, ax + +xor ecx, ecx ; Calculate bytes in a cluster +mov cl, [SpClst] +imul cx, [BpSect] + +imul eax, ecx +add eax, [BegData] ; Start of cluster + +shr ecx, 2 ; Cluster size in dwords +mov esi, eax ; Copy source +mov edi, [CurrDst] ; Copy destination +call CopyData32 + +mov [CurrDst], edi ; Update dest +pop ax ; Restore cluster number + +ret + +; Search FAT (FAT12 format) for next cluster in file after `ax'. + +NextCluster: + +movzx ecx, ax ; Calculate offset into FAT +shr ax, 1 +pushf +add cx, ax + +mov esi, [BegFAT] ; Copy word containing next cluster to buffer +add esi, ecx +mov edi, RelocBase + Buffer +xor ecx, ecx +inc ecx +call CopyData32 + +mov ax, [Buffer] ; Handle odd/even cluster numbers +popf +jnc EvenCluster +shr ax, 4 + +EvenCluster: + +and ax, 0FFFh +ret + +; Enable the A20 line for accesses to extended memory. + +EnableA20: + in al,92h + or al,2 + jmp short $+2 + jmp short $+2 + jmp short $+2 + out 92h,al + ret + +; The CopyData32 routine copies ecx dwords from esi to edi. Both esi +; and edi hold 32-bit values. CopyData32 runs in 32-bit protected mode. + +CopyData32: + cli + + call EnableA20 ; Put here in case file I/O screws with this + ; or with the GDTR + + lgdt [GDTStart] ; Initialize GDTR for 32-bit protected mode + + mov eax, cr0 + or al, 1 + mov cr0, eax ;go to real flat mode + +; LED_GRN +; PSW_WAIT + + jmp dword 8h : RelocBase+ProtJmp +[bits 32] +ProtJmp: +; LED_YEL +; PSW_WAIT + + mov ax, 10h + mov ds, ax + mov es, ax + mov ss, ax + + rep movsd ;copy the sector to where it should be + + mov ax, 20h + mov ds, ax + mov es, ax + mov ss, ax + +; LED_RED +; PSW_WAIT + + jmp 18h : RealJmp1 ;use code segment with 64K limit +[bits 16] +RealJmp1: +; LED_OFF +; PSW_WAIT + + mov eax, cr0 ;back to real segmented mode + and eax, 0fffffffeh + mov cr0, eax + + jmp RelocSeg : RealJmp2 +RealJmp2: +; LED_GRN +; PSW_WAIT + + mov ax, cs + mov es, ax + mov ds, ax + mov ss, ax + + sti +ret + +; Storage for a Dos 3+ BIOS Parameter Block (for the C: ramdisk) + +SavBPB: + +BpSect dw 0h ; Bytes per sector, always 512 +SpClst db 0h ; Sectors per cluster +ResSec dw 0h ; Num of reserved sectors +NumFAT db 0h ; Num of FATs +NRoot dw 0h ; Num of root directory entries +TotSec dw 0h ; Total sectors +Media db 0h ; Media descriptor byte +SecFAT dw 0h ; Sectors per FAT + +EndBPB: + +CurrDst dd 0h ; Current destination address for copying RTEMS exec + +; Important (32-bit) address for the C: ramdisk + +BegFAT dd 0h ; Start of the FAT +BegRoot dd 0h ; Start of root directory +BegData dd 0h ; Start of data clusters + +DDrive db 0h ; Default drive: 0h = A:, 2h = C: + +DirName times 11 db 32 ; Room for 8.3 directory entry name + +FName times 13 db 0 ; Room for a 12 character null-terminated string +FHndl dw 0000h + +Greet db "RTEMS DOS Loader (c) 1999 Tony R. Ambardar",13,10,"$" +Button db "Button pressed -- Aborting.",13,10,"$" +FError db "Missing or incorrect file name.",13,10,"$" +RError db "Error opening or reading file.",13,10,"$" + +; Global Descriptor Table used for protectd mode. +; Store the GDTR in the first null GDT entry + +GDTStart: + +dw GDTEnd - GDTStart - 1 +dd RelocBase + GDTStart +dw 0 + +; base=0h, limit=4Gb, present, code, exec/read, conform, 32-bit + +dw 0ffffh ;seg. lim. [15:0] +dw 0 ;base[15:0] +db 0 ;base[23:16] +db 9eh ;p=1,dpl=0,s=1 ; code: execute/read, conforming +db 0cfh ;c: gran=4K, D/B=1(32-bit) ; f: seg. lim. [19:16] +db 0 ;base[31:24] + +; base=0h, limit=4Gb, present, data, read/write exp. up, 32-bit SP + +dw 0ffffh ;seg. lim. [15:0] +dw 0 ;base[15:0] +db 0 ;base[23:16] +db 92h ;p=1,dpl=0,s=1 ; data: read/write expand-up +db 0cfh ;c: gran=4K, D/B=1(32-bit) ; f: seg. lim. [19:16] +db 0 ;base[31:24] + +; base=0h, limit=ffffh, present, code, exec/read, conform, 16-bit +; NOTE: this descriptor is used to change back to real mode. + +dw 0ffffh ;seg. lim. [15:0] +dw Reloc15 ;base[15:0] +db Reloc23 ;base[23:16] +db 9eh ;p=1,dpl=0,s=1 ; code: execute/read, conforming +db 000h ;4: gran=1 byte, D/B=0(16-bit) ; 0: seg. lim. [19:16] +db 0 ;base[31:24] + +; base=0h, limit=ffffh, present, data, read/write exp. up, 16-bit SP +; NOTE: this descriptor is used to change back to real mode. + +dw 0ffffh ;seg. lim. [15:0] +dw Reloc15 ;base[15:0] +db Reloc23 ;base[23:16] +db 92h ;p=1,dpl=0,s=1 ; data: read/write expand-up +db 000h ;0: gran=1 byte, D/B=0(16-bit) ; 0: seg. lim. [19:16] +db 0 ;base[31:24] + +GDTEnd: + +CodeEnd: ; end-of-code marker for copy diff --git a/c/src/lib/libbsp/i386/ts_386ex/tools/dos_sup/ts1325.inc b/c/src/lib/libbsp/i386/ts_386ex/tools/dos_sup/ts1325.inc new file mode 100644 index 0000000000..40ed3659ab --- /dev/null +++ b/c/src/lib/libbsp/i386/ts_386ex/tools/dos_sup/ts1325.inc @@ -0,0 +1,48 @@ +; Some nasm macros to turn on TS-1325 LEDs and wait for button presses. +; This should be '%include'ed in your nasm source file. +; +; Tony Ambardar + +P1LTC equ 0F862h +P1PIN equ 0F860h + +%macro LED_OFF 0 + mov dx, P1LTC + in al, dx + or al, 01000000b ; turn off red + and al, 11011111b ; turn off green + out dx, al +%endmacro + +%macro LED_GRN 0 + mov dx, P1LTC + in al, dx + or al, 01100000b ; turn off red, turn on green + out dx, al +%endmacro + +%macro LED_YEL 0 + mov dx, P1LTC + in al, dx + or al, 00100000b ; turn on green + and al, 10111111b ; turn on red + out dx, al +%endmacro + +%macro LED_RED 0 + mov dx, P1LTC + in al, dx + and al, 10011111b ; turn on red, turn off green + out dx, al +%endmacro + +%macro PSW_WAIT 0 + mov dx, P1PIN ; Get PSW state + mov ecx, 80000h +%%read in al, dx + test al, 00000001b ; is PSW asserted? + jnz %%read ; if not, we're done + dec ecx + jnz %%read +%endmacro + diff --git a/c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/Makefile b/c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/Makefile new file mode 100644 index 0000000000..1ce881e04e --- /dev/null +++ b/c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/Makefile @@ -0,0 +1,41 @@ +# +# Makefile for TS-1325 Utilities example +# + +MAIN=ts1325_test + +# Tool paths +tooldir=/usr/local/rtems +rtemsdir=${tooldir}/rtems/ts_386ex + +# Tool names +GCC=${tooldir}/bin/i386-rtems-gcc +GNATMAKE=${tooldir}/bin/i386-rtems-gnatmake +SIZE=${tooldir}/bin/i386-rtems-size +SIS=${tooldir}/bin/sis +GDB=${tooldir}/bin/sis-gdb + +CARGS=-B${rtemsdir}/lib/ -specs bsp_specs -qrtems \ +-msoft-float -mno-fp-ret-in-387 +#CARGS=-B/usr/local/rtems/tools/build-i386-rtems/ts_386ex/lib/ -specs bsp_specs -qrtems + +all: init.o + $(GNATMAKE) -O -gnata -gnatE -gnato $(MAIN) -g \ + -bargs -r \ + -cargs $(CARGS) \ + -largs $(CARGS) init.o + $(SIZE) $(MAIN) + + + +init.o: init.c + $(GCC) -O4 -g -Wall -ansi -fasm $(CARGS) -c init.c + +run: + $(SIS) $(MAIN) + +gdb: + $(GDB) $(MAIN) + +clean: + rm -f b_$(MAIN).c b_$(MAIN).o *.o *.ali $(MAIN) diff --git a/c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/Makefile.ts_386ex b/c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/Makefile.ts_386ex new file mode 100644 index 0000000000..1ce881e04e --- /dev/null +++ b/c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/Makefile.ts_386ex @@ -0,0 +1,41 @@ +# +# Makefile for TS-1325 Utilities example +# + +MAIN=ts1325_test + +# Tool paths +tooldir=/usr/local/rtems +rtemsdir=${tooldir}/rtems/ts_386ex + +# Tool names +GCC=${tooldir}/bin/i386-rtems-gcc +GNATMAKE=${tooldir}/bin/i386-rtems-gnatmake +SIZE=${tooldir}/bin/i386-rtems-size +SIS=${tooldir}/bin/sis +GDB=${tooldir}/bin/sis-gdb + +CARGS=-B${rtemsdir}/lib/ -specs bsp_specs -qrtems \ +-msoft-float -mno-fp-ret-in-387 +#CARGS=-B/usr/local/rtems/tools/build-i386-rtems/ts_386ex/lib/ -specs bsp_specs -qrtems + +all: init.o + $(GNATMAKE) -O -gnata -gnatE -gnato $(MAIN) -g \ + -bargs -r \ + -cargs $(CARGS) \ + -largs $(CARGS) init.o + $(SIZE) $(MAIN) + + + +init.o: init.c + $(GCC) -O4 -g -Wall -ansi -fasm $(CARGS) -c init.c + +run: + $(SIS) $(MAIN) + +gdb: + $(GDB) $(MAIN) + +clean: + rm -f b_$(MAIN).c b_$(MAIN).o *.o *.ali $(MAIN) diff --git a/c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/i386_ports.adb b/c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/i386_ports.adb new file mode 100644 index 0000000000..9705d069d8 --- /dev/null +++ b/c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/i386_ports.adb @@ -0,0 +1,29 @@ +with System.Machine_Code; +use System.Machine_Code; + +package body I386_Ports is + + procedure Outport (Addr: in Port_Address; Data: in Byte) is + begin + Asm ("movb %0, %%al;" & + "movw %1, %%dx;" & + "outb %%al, %%dx", + No_Output_Operands, + (Byte'Asm_Input ("g", Data), + Port_Address'Asm_Input ("g", Addr)), + Clobber => "al dx", + Volatile => True); + end Outport; + + procedure Inport (Addr: in Port_Address; Data: out Byte) is + begin + Asm ("movw %1, %%dx;" & + "inb %%dx, %%al;" & + "movb %%al, %0", + Byte'Asm_Output ("=g", Data), + Port_Address'Asm_Input ("g", Addr), + Clobber => "dx al", + Volatile => True); + end Inport; + +end I386_Ports; diff --git a/c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/i386_ports.ads b/c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/i386_ports.ads new file mode 100644 index 0000000000..c27ea646e7 --- /dev/null +++ b/c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/i386_ports.ads @@ -0,0 +1,47 @@ +with Interfaces; + +package I386_Ports is + + type Port_Address is new Interfaces.Unsigned_16; + + type Byte is new Interfaces.Unsigned_8; + + type Word is new Interfaces.Unsigned_16; + + type Long is new Interfaces.Unsigned_32; + + procedure Outport (Addr: in Port_Address; Data: in Byte); + + procedure Inport (Addr: in Port_Address; Data: out Byte); + + P1PIN: constant Port_Address; + P1LTC: constant Port_Address; + P1DIR: constant Port_Address; + + P2PIN: constant Port_Address; + P2LTC: constant Port_Address; + P2DIR: constant Port_Address; + + P3PIN: constant Port_Address; + P3LTC: constant Port_Address; + P3DIR: constant Port_Address; + +private + + pragma Inline (Outport, Inport); + + P1PIN: constant Port_Address := 16#F860#; + P1LTC: constant Port_Address := 16#F862#; + P1DIR: constant Port_Address := 16#F864#; + + P2PIN: constant Port_Address := 16#F868#; + P2LTC: constant Port_Address := 16#F86A#; + P2DIR: constant Port_Address := 16#F86C#; + + P3PIN: constant Port_Address := 16#F870#; + P3LTC: constant Port_Address := 16#F872#; + P3DIR: constant Port_Address := 16#F874#; + +end I386_Ports; + + diff --git a/c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/init.c b/c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/init.c new file mode 100644 index 0000000000..89e1652f3f --- /dev/null +++ b/c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/init.c @@ -0,0 +1,86 @@ +/* + * COPYRIGHT (c) 1989-1997. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * 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 + +#ifdef GNAT_PID +#include +pid_t getpid() +{ + return GNAT_PID; +} +#endif + +/* + * By having the POSIX_Init thread create a second thread just + * to invoke gnat_main, we can override all default attributes + * of the "Ada environment task". Otherwise, we would be + * stuck with the defaults set by RTEMS. + */ + +void *start_gnat_main( void * argument ) +{ + extern int gnat_main ( int argc, char **argv, char **envp ); + + (void) gnat_main ( 0, 0, 0 ); + + exit( 0 ); + + return 0; +} + +void *POSIX_Init( void *argument ) +{ + pthread_t thread_id; + pthread_attr_t attr; + int status; + + status = pthread_attr_init( &attr ); + assert( !status ); + +#ifdef GNAT_MAIN_STACKSPACE + status = pthread_attr_setstacksize( &attr, GNAT_MAIN_STACKSPACE ); + assert( !status ); +#endif + + status = pthread_create( &thread_id, &attr, start_gnat_main, NULL ); + assert( !status ); + + pthread_exit( 0 ); + + return 0; +} + +/* configuration information */ + +#define CONFIGURE_SPTEST +#define CONFIGURE_GNAT_RTEMS + +#define CONFIGURE_TEST_NEEDS_CONSOLE_DRIVER +#define CONFIGURE_TEST_NEEDS_CLOCK_DRIVER + +#define CONFIGURE_MICROSECONDS_PER_TICK RTEMS_MILLISECONDS_TO_MICROSECONDS(1) + +#define CONFIGURE_POSIX_INIT_THREAD_TABLE + +#define CONFIGURE_MAXIMUM_POSIX_THREADS 20 +#define CONFIGURE_MAXIMUM_POSIX_KEYS 20 +#define CONFIGURE_MAXIMUM_POSIX_MUTEXES 30 +#define CONFIGURE_MAXIMUM_POSIX_CONDITION_VARIABLES 20 + +#define CONFIGURE_INIT + +#include + diff --git a/c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/ts1325-button.adb b/c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/ts1325-button.adb new file mode 100644 index 0000000000..cc273b0b3f --- /dev/null +++ b/c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/ts1325-button.adb @@ -0,0 +1,22 @@ +package body TS1325.Button is + + function Is_Button_Pressed return Boolean is + State: Byte; + begin + Inport (Button_Port, State); + return (State and Button_Mask) /= Button_Mask; + end Is_Button_Pressed; + + procedure Wait_For_Button_Press is + begin + Poll_Loop: + loop + if Is_Button_Pressed then + delay Minimum_Press_Time; + exit Poll_Loop when Is_Button_Pressed; + end if; + delay Poll_Interval; + end loop Poll_Loop; + end Wait_For_Button_Press; + +end TS1325.Button; diff --git a/c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/ts1325-button.ads b/c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/ts1325-button.ads new file mode 100644 index 0000000000..568710b32f --- /dev/null +++ b/c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/ts1325-button.ads @@ -0,0 +1,22 @@ +with I386_Ports; +use I386_Ports; + +package TS1325.Button is + + function Is_Button_Pressed return Boolean; + + procedure Wait_For_Button_Press; + +private + + pragma Inline (Is_Button_Pressed, Wait_For_Button_Press); + + Poll_Interval: constant Duration := 0.3; + + Minimum_Press_Time: constant Duration := 0.3; + + Button_Mask: constant Byte := 2#0000_0001#; + + Button_Port: Port_Address renames P1PIN; + +end TS1325.Button; diff --git a/c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/ts1325-led.adb b/c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/ts1325-led.adb new file mode 100644 index 0000000000..1a213ac2ff --- /dev/null +++ b/c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/ts1325-led.adb @@ -0,0 +1,46 @@ +package body TS1325.LED is + + protected body LED_State is + + function Get return LED_Colour is + State: Byte; + Red_On, Green_On: Boolean; + begin + Inport (LED_Port, State); + + Green_On := (State and Green_Bit) = Green_Bit; + Red_On := (State and Red_Bit) /= Red_Bit; + + if not (Green_On or Red_On) then + return Off; + elsif Green_On and not Red_On then + return Green; + elsif Green_On and Red_On then + return Yellow; + else + return Red; + end if; + end Get; + + procedure Set (Col: in LED_Colour) is + State: Byte; + begin + Inport (LED_Port, State); + + case Col is + when Off => + State := (State and not Green_Bit) or Red_Bit; + when Green => + State := State or Green_Bit or Red_Bit; + when Yellow => + State := (State or Green_Bit) and not Red_Bit; + when Red => + State := State and not (Green_Bit or Red_Bit); + end case; + + Outport (LED_Port, State); + end Set; + + end LED_State; + +end TS1325.LED; diff --git a/c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/ts1325-led.ads b/c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/ts1325-led.ads new file mode 100644 index 0000000000..6856bc4520 --- /dev/null +++ b/c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/ts1325-led.ads @@ -0,0 +1,26 @@ +with I386_Ports; +use I386_Ports; + +package TS1325.LED is + + type LED_Colour is (Off, Green, Yellow, Red); + + protected LED_State is + + function Get return LED_Colour; + + procedure Set (Col: in LED_Colour); + + end LED_State; + +private + + Green_Bit: constant Byte := 2#0010_0000#; -- bit set = LED on + + Red_Bit: constant Byte := 2#0100_0000#; -- bit clear = LED on + + LED_Mask: constant Byte := 2#0110_0000#; + + LED_Port: Port_Address renames P1LTC; + +end TS1325.LED; diff --git a/c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/ts1325-parallel.adb b/c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/ts1325-parallel.adb new file mode 100644 index 0000000000..c0a76bcadf --- /dev/null +++ b/c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/ts1325-parallel.adb @@ -0,0 +1,13 @@ +package body TS1325.Parallel is + + procedure Read_Parallel_Port (Data: out Byte) is + begin + Inport (Parallel_Port_In, Data); + end Read_Parallel_Port; + + procedure Write_Parallel_Port (Data: in Byte) is + begin + Outport (Parallel_Port_Out, Data); + end Write_Parallel_Port; + +end TS1325.Parallel; diff --git a/c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/ts1325-parallel.ads b/c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/ts1325-parallel.ads new file mode 100644 index 0000000000..b6b18d6b55 --- /dev/null +++ b/c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/ts1325-parallel.ads @@ -0,0 +1,21 @@ +with I386_Ports; +use I386_Ports; + +package TS1325.Parallel is + + procedure Read_Parallel_Port (Data: out Byte); + + procedure Write_Parallel_Port (Data: in Byte); + +private + + pragma Inline (Read_Parallel_Port, Write_Parallel_Port); + + -- These are non-standard IO locations, which is why they are here instead + -- of in the I386_Ports package. + + Parallel_Port_In: constant Port_Address := 16#75#; + + Parallel_Port_Out: constant Port_Address := 16#74#; + +end TS1325.Parallel; diff --git a/c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/ts1325.ads b/c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/ts1325.ads new file mode 100644 index 0000000000..5ef01b7449 --- /dev/null +++ b/c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/ts1325.ads @@ -0,0 +1,2 @@ +package TS1325 is +end TS1325; diff --git a/c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/ts1325_test.adb b/c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/ts1325_test.adb new file mode 100644 index 0000000000..0cb621c880 --- /dev/null +++ b/c/src/lib/libbsp/i386/ts_386ex/tools/ts_1325_ada/ts1325_test.adb @@ -0,0 +1,115 @@ +-- +-- A test program that uses the TS1325 Button and LED packages. +-- + +with Text_IO; + +with I386_Ports; +use I386_Ports; + +with TS1325.LED; +use TS1325.LED; + +with TS1325.Button; +use TS1325.Button; + +with TS1325.Parallel; +use TS1325.Parallel; + +procedure Ts1325_Test is + + Test_Parallel_Interval: Duration := 1.0; + Read_Button_Interval: Duration := 1.0; + Read_LED_Interval: Duration := 1.0; + Set_LED_Interval: Duration := 0.2; + + task Test_Parallel is + entry Start; + end Test_Parallel; + + task body Test_Parallel is + W_Data, R_Data: I386_Ports.Byte := 0; + begin + accept Start; + + loop + W_Data := W_Data + 1; + Write_Parallel_Port (W_Data); + Read_Parallel_Port (R_Data); + Text_IO.Put_Line ("Parallel Port Loopback: Data Write = " & + I386_Ports.Byte'Image (W_Data) & + ", Data Read = " & + I386_Ports.Byte'Image (R_Data)); + delay Test_Parallel_Interval; + end loop; + end Test_Parallel; + + task Read_Button is + entry Start; + end Read_Button; + + task body Read_Button is + begin + accept Start; + + loop + if Is_Button_Pressed then + Text_IO.Put_Line ("Button is pressed."); + else + Text_IO.Put_Line ("Button is not pressed."); + end if; + delay Read_Button_Interval; + end loop; + end Read_Button; + + task Read_Colour is + entry Start; + end Read_Colour; + + task body Read_Colour is + begin + accept Start; + + loop + Text_IO.Put_Line ("Reading LED colour as " & + LED_Colour'Image (LED_State.Get)); + delay Read_LED_Interval; + end loop; + end Read_Colour; + + task Set_Colour is + entry Start; + end Set_Colour; + + task body Set_Colour is + Colour: LED_Colour := Off; + begin + accept Start; + + loop + LED_State.Set (Colour); + + if Colour = LED_Colour'Last then + Colour := LED_Colour'First; + else + Colour := LED_Colour'Succ (Colour); + end if; + + delay Set_LED_Interval; + end loop; + end Set_Colour; + +begin + Text_IO.Put_Line ("TS-1325 Utilities Test"); + Text_IO.Put_Line ("======================"); + Text_IO.New_Line; + Text_IO.Put_Line ("-=> Press the button to begin."); + Text_IO.New_Line; + + Wait_For_Button_Press; + + Set_Colour.Start; + Read_Colour.Start; + Read_Button.Start; + Test_Parallel.Start; +end Ts1325_Test; diff --git a/c/src/lib/libbsp/i386/ts_386ex/wrapup/Makefile.in b/c/src/lib/libbsp/i386/ts_386ex/wrapup/Makefile.in new file mode 100644 index 0000000000..f824af4c6c --- /dev/null +++ b/c/src/lib/libbsp/i386/ts_386ex/wrapup/Makefile.in @@ -0,0 +1,70 @@ +# +# $Id$ +# + +@SET_MAKE@ +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +top_builddir = ../../../../../../.. +subdir = c/src/lib/libbsp/i386/ts_386ex/wrapup + +INSTALL = @INSTALL@ + +# We only build the Network library if HAS_NETWORKING was defined +NETWORK_yes_V = network +NETWORK = $(NETWORK_$(HAS_NETWORKING)_V) + +RTEMS_ROOT = $(top_srcdir)/@RTEMS_TOPdir@ +PROJECT_ROOT = @PROJECT_ROOT@ + +VPATH = @srcdir@ + +BSP_PIECES=startup clock console timer $(NETWORK) +GENERIC_PIECES= + +# bummer; have to use $foreach since % pattern subst rules only replace 1x +OBJS=$(foreach piece, $(BSP_PIECES), ../$(piece)/$(ARCH)/$(piece).rel) \ + $(foreach piece, $(GENERIC_PIECES), ../../../$(piece)/$(ARCH)/$(piece).rel) +LIB=$(ARCH)/libbsp.a + +include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg +include $(RTEMS_ROOT)/make/lib.cfg + +# +# (OPTIONAL) Add local stuff here using += +# + +DEFINES += +CPPFLAGS += +CFLAGS += + +LD_PATHS += +LD_LIBS += +LDFLAGS += + +# +# Add your list of files to delete here. The config files +# already know how to delete some stuff, so you may want +# to just run 'make clean' first to see what gets missed. +# 'make clobber' already includes 'make clean' +# + +CLEAN_ADDITIONS += +CLOBBER_ADDITIONS += + +$(LIB): ${OBJS} + $(make-library) + +all: ${ARCH} $(SRCS) $(LIB) + $(INSTALL_VARIANT) -m 644 $(LIB) ${PROJECT_RELEASE}/lib + +install: all + +$(PROJECT_ROOT)/${RTEMS_BSP}/lib/bsp_specs: ../bsp_specs + $(INSTALL_DATA) $< $@ + +preinstall: $(PROJECT_ROOT)/${RTEMS_BSP}/lib/bsp_specs + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status -- cgit v1.2.3