summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1998-10-05 22:36:06 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1998-10-05 22:36:06 +0000
commit0ebbf66b0ee518763ee38b4ac28c7d3b6feaadf1 (patch)
tree4092e08f36cef683d4eb0b38687023b93f33b63c
parentNew file based on information from Eric Norum <eric@skatter.usask.ca>. (diff)
downloadrtems-0ebbf66b0ee518763ee38b4ac28c7d3b6feaadf1.tar.bz2
Large patch from Erik Ivanenko <erik.ivanenko@utoronto.ca> which
moves pieces of the pc386 bsp up to a shared level for all i386 BSPs and modifies the i386ex BSP to use those shared pieces. Serial remote debugging is included for both targets. Erik's notes: There are several workarounds in it: 1) #define NEXT_GAS is hardcoded in pc386/start/start.s 2) #define NEXT_GAS is hardcoded in i386ex/start/start.s 3) #define NEW_GAS is hardcoded in pc386/start16.s 4) #undef __assert and redeclare _assert hardcoded in console.c for both pc386 and i386ex due to my egcs1.1b ~ newlib problem. Should have modified t-rtems.cfg ( no time ) I've tested pc386 with both video and serial consoles and GDB remote. All work fine, except that GDB acts weird. ( re: other posting) I hope this will work for you. It took quite some time to locate the autoconf error. The remainder was just grunt work. Unfortunately, I think I've unwound the removal of the IBMPCInitVideo stuff. Sorry. I REALLY can't spend more time... I've been at this conversion to 4.0 locally and updating the release since Sept. 8th, and have yet to compile my network driver.... This is as much as I can do right now. I look forward to the next patch to really test i368ex. I did make sure that the sample tests worked for pc386.
-rw-r--r--c/src/lib/libbsp/i386/i386ex/clock/ckinit.c8
-rw-r--r--c/src/lib/libbsp/i386/i386ex/console/console.c576
-rw-r--r--c/src/lib/libbsp/i386/i386ex/start/Makefile.in1
-rw-r--r--c/src/lib/libbsp/i386/i386ex/startup/Makefile.in15
-rw-r--r--c/src/lib/libbsp/i386/i386ex/timer/timer.c6
-rw-r--r--c/src/lib/libbsp/i386/pc386/Makefile.in2
-rw-r--r--c/src/lib/libbsp/i386/pc386/clock/ckinit.c8
-rw-r--r--c/src/lib/libbsp/i386/pc386/console/console.c89
-rw-r--r--c/src/lib/libbsp/i386/pc386/include/bsp.h8
-rw-r--r--c/src/lib/libbsp/i386/pc386/start/Makefile.in4
-rw-r--r--c/src/lib/libbsp/i386/pc386/start/start16.s2
-rw-r--r--c/src/lib/libbsp/i386/pc386/startup/Makefile.in4
-rw-r--r--c/src/lib/libbsp/i386/pc386/startup/bspstart.c1
-rw-r--r--c/src/lib/libbsp/i386/pc386/startup/exit.c2
-rw-r--r--c/src/lib/libbsp/i386/pc386/startup/linkcmds1
-rw-r--r--c/src/lib/libbsp/i386/pc386/timer/timer.c8
-rw-r--r--c/src/lib/libbsp/i386/pc386/wrapup/Makefile.in2
-rw-r--r--c/src/lib/libbsp/i386/shared/Makefile.in2
-rw-r--r--c/src/lib/libbsp/i386/shared/comm/GDB.HOWTO177
-rw-r--r--c/src/lib/libbsp/i386/shared/comm/Makefile.in33
-rw-r--r--c/src/lib/libbsp/i386/shared/comm/i386-stub-glue.c194
-rw-r--r--c/src/lib/libbsp/i386/shared/comm/i386-stub.c937
-rw-r--r--c/src/lib/libbsp/i386/shared/comm/uart.c935
-rw-r--r--c/src/lib/libbsp/i386/shared/comm/uart.h169
-rw-r--r--c/src/lib/libbsp/i386/shared/irq/irq.c60
-rw-r--r--c/src/lib/libbsp/i386/shared/irq/irq.h48
-rw-r--r--c/src/lib/libbsp/i386/shared/irq/irq_asm.h2
-rw-r--r--c/src/lib/libbsp/i386/shared/irq/irq_init.c20
-rw-r--r--c/src/lib/libbsp/i386/shared/pci/Makefile.in32
-rw-r--r--c/src/lib/libbsp/i386/shared/pci/pcibios.c499
-rw-r--r--c/src/lib/libbsp/i386/shared/pci/pcibios.h46
31 files changed, 3515 insertions, 376 deletions
diff --git a/c/src/lib/libbsp/i386/i386ex/clock/ckinit.c b/c/src/lib/libbsp/i386/i386ex/clock/ckinit.c
index 6259b2d423..091d6fab45 100644
--- a/c/src/lib/libbsp/i386/i386ex/clock/ckinit.c
+++ b/c/src/lib/libbsp/i386/i386ex/clock/ckinit.c
@@ -77,7 +77,7 @@ int ClockIsOn(const rtems_irq_connect_data* unused)
return ((i8259s_cache & 0x1) == 0);
}
-static rtems_irq_connect_data clockIrqData = {PC_386_PERIODIC_TIMER,
+static rtems_irq_connect_data clockIrqData = {BSP_PERIODIC_TIMER,
Clock_isr,
ClockOn,
ClockOff,
@@ -114,7 +114,7 @@ rtems_device_driver Clock_initialize(
outport_byte ( TMR0 , clock_lsb ); /* load LSB first */
outport_byte ( TMR0 , clock_msb ); /* then MSB */
- if (!pc386_install_rtems_irq_handler (&clockIrqData)) {
+ if (!BSP_install_rtems_irq_handler (&clockIrqData)) {
printk("Unable to initialize system clock\n");
rtems_fatal_error_occurred(1);
}
@@ -151,7 +151,7 @@ rtems_device_driver Clock_control(
}
else if (args->command == rtems_build_name('N', 'E', 'W', ' '))
{
- if (!pc386_install_rtems_irq_handler (&clockIrqData)) {
+ if (!BSP_install_rtems_irq_handler (&clockIrqData)) {
printk("Error installing clock interrupt handler!\n");
rtems_fatal_error_occurred(1);
}
@@ -168,5 +168,5 @@ done:
void Clock_exit()
{
ClockOff(&clockIrqData);
- pc386_remove_rtems_irq_handler (&clockIrqData);
+ BSP_remove_rtems_irq_handler (&clockIrqData);
}
diff --git a/c/src/lib/libbsp/i386/i386ex/console/console.c b/c/src/lib/libbsp/i386/i386ex/console/console.c
index c535d7efad..84458d5028 100644
--- a/c/src/lib/libbsp/i386/i386ex/console/console.c
+++ b/c/src/lib/libbsp/i386/i386ex/console/console.c
@@ -1,295 +1,401 @@
-/*
- * This file contains the i386ex console IO package.
- *
- * 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$
- */
+/*-------------------------------------------------------------------------+
+| 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 <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
-#define F386_INIT
+/* workaround for gcc development tools */
+#undef __assert
+void __assert (const char *file, int line, const char *msg);
#include <bsp.h>
+#include <irq.h>
#include <rtems/libio.h>
-#include <bspIo.h>
-#include <stdlib.h>
+#include <termios.h>
+#include <uart.h>
+#include <libcpu/cpuModel.h>
-#include "../start/80386ex.h"
-
-/* console_cleanup
- *
- * This routine is called at exit to clean up the console hardware.
- *
- * Input parameters: NONE
- *
- * Output parameters: NONE
- *
- * Return values:
+/*
+ * 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.
*/
-void console_cleanup( void )
-{
- register rtems_unsigned8 ignored;
+int BSPConsolePort = BSP_UART_COM2;
+int BSPBaseBaud = 781250;
+int BSP_poll_read(int);
+
+extern BSP_polling_getchar_function_type BSP_poll_char;
-/* clear the read buffer */
+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.
+ */
- inport_byte( RBR0, ignored );
+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;
}
-/* console_initialize
- *
- * This routine initializes the console IO driver.
- *
- * Input parameters: NONE
- *
- * Output parameters: NONE
- *
- * Return values:
- */
+static int
+isr_is_on(const rtems_irq_connect_data *irq)
+{
+ return BSP_irq_enabled_at_i8259s(irq->name);
+}
-rtems_device_driver console_initialize(
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void *arg
-)
+void console_reserve_resources(rtems_configuration_table *conf)
{
- rtems_status_code status;
+ 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;
+
/*
- * flush the console now and at exit. Just in case.
+ * Note we cannot call exit or printf from here,
+ * assert can fail inside ISR too
*/
- console_cleanup();
+ /*
+ * Close console
+ */
+ __rtems_close(2);
+ __rtems_close(1);
+ __rtems_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");
+}
- status = rtems_io_register_name(
- "/dev/console",
- major,
- (rtems_device_minor_number) 0
- );
-
- if (status != RTEMS_SUCCESSFUL)
+
+/*-------------------------------------------------------------------------+
+| 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
+ */
+
+ /* 9600-8-N-1, no hardware flow control */
+ BSP_uart_init(BSPConsolePort, 9600, 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);
-
- atexit( console_cleanup );
+ }
+ /*
+ * 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 9600-8-N-1\n\n");
+ }
+ else
+ {
+ printk("Initialized console on port COM2 9600-8-N-1\n\n");
+ }
return RTEMS_SUCCESSFUL;
-}
+} /* console_initialize */
-/* is_character_ready
- *
- * This routine returns TRUE if a character is available.
- *
- * Input parameters: NONE
- *
- * Output parameters: NONE
- *
- * Return values:
- */
+static int console_open_count = 0;
-rtems_boolean is_character_ready(
- char *ch
-)
+static int console_last_close(int major, int minor, void *arg)
{
- register rtems_unsigned8 status;
+ BSP_remove_rtems_irq_handler (&console_isr_data);
- inport_byte( LSR1, status );
-
- if ( Is_rx_ready( status ) ) {
- inport_byte( RBR1, status );
- *ch = status;
- return TRUE;
- }
- return FALSE;
+ return 0;
}
-/*
- * Wait for an input. May be used before intr are ON.
- */
-char BSP_wait_polled_input( void )
+/*-------------------------------------------------------------------------+
+| Console device driver OPEN entry point
++--------------------------------------------------------------------------*/
+rtems_device_driver
+console_open(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg)
{
- char c;
- while (!is_character_ready(&c))
- continue;
-
- return c;
-}
-
-/* inbyte
- *
- * This routine reads a character from the UART.
- *
- * Input parameters: NONE
- *
- * Output parameters: NONE
- *
- * Return values:
- * character read from UART
- */
+ 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;
+ }
-char inbyte( void )
-{
- register rtems_unsigned8 status;
- char ch;
+ status = rtems_termios_open (major, minor, arg, &cb);
- do {
- inport_byte( LSR1, status );
- } while ( !( status & 0x01 ));/* s/b while ( !( Is_rx_ready( status ) ) ); */
+ if(status != RTEMS_SUCCESSFUL)
+ {
+ printk("Error openning console device\n");
+ return status;
+ }
- inport_byte( RBR1, ch );
+ /*
+ * 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 ch;
+ return RTEMS_SUCCESSFUL;
}
-/* outbyte
- *
- * This routine transmits a character out the port. It supports
- * XON/XOFF flow control.
- *
- * Input parameters:
- * ch - character to be transmitted
- *
- * Output parameters: NONE
- */
-
-void outbyte(
- char ch
-)
+/*-------------------------------------------------------------------------+
+| Console device driver CLOSE entry point
++--------------------------------------------------------------------------*/
+rtems_device_driver
+console_close(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg)
{
- rtems_unsigned8 status;
- do {
- inport_byte( LSR1, status );
- } while ( ! ( 0x40 & status ) ); /* ( Is_tx_ready( status ) ) );*/
-
-/*
- * GDB will NOT use XON/XOFF protocol
- */
-
-
-#ifdef USE_XON
+ return (rtems_termios_close (arg));
- while ( is_character_ready( &status ) == TRUE ) {
- if ( status == XOFF )
- do {
- while ( is_character_ready( &status ) == FALSE ) ;
- } while ( status != XON );
- }
+} /* console_close */
-#endif
+
+/*-------------------------------------------------------------------------+
+| 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;
+ printf("read the console\n");
- outport_byte( TBR1, ch );
+ sc = rtems_termios_read (arg);
-}
+ if ( sc != RTEMS_SUCCESSFUL )
+ printf("console_read: fails %s\n",rtems_status_text(sc));
-/*
- * Open entry point
- */
+ return sc;
+
+} /* console_read */
-rtems_device_driver console_open(
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void * arg
-)
+
+/*-------------------------------------------------------------------------+
+| 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_SUCCESSFUL;
-}
+ return rtems_termios_write (arg);
-/*
- * Close entry point
- */
-
-rtems_device_driver console_close(
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void * arg
-)
-{
- return RTEMS_SUCCESSFUL;
-}
+} /* console_write */
+
+
/*
- * read bytes from the serial port. We only have stdin.
+ * Handle ioctl request.
*/
-
-rtems_device_driver console_read(
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void * arg
+rtems_device_driver
+console_control(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
)
-{
- rtems_libio_rw_args_t *rw_args;
- char *buffer;
- int maximum;
- int count = 0;
-
- rw_args = (rtems_libio_rw_args_t *) arg;
-
- buffer = rw_args->buffer;
- maximum = rw_args->count;
-
- for (count = 0; count < maximum; count++) {
- buffer[ count ] = inbyte();
- if (buffer[ count ] == '\n' || buffer[ count ] == '\r') {
- buffer[ count++ ] = '\n';
- break;
- }
- }
-
- rw_args->bytes_moved = count;
- return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED;
+{
+ return rtems_termios_ioctl (arg);
}
-/*
- * write bytes to the serial port. Stdout and stderr are the same.
- */
-
-rtems_device_driver console_write(
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void * arg
-)
+static int
+conSetAttr(int minor, const struct termios *t)
{
- int count;
- int maximum;
- rtems_libio_rw_args_t *rw_args;
- char *buffer;
-
- rw_args = (rtems_libio_rw_args_t *) arg;
-
- buffer = rw_args->buffer;
- maximum = rw_args->count;
-
- for (count = 0; count < maximum; count++) {
- if ( buffer[ count ] == '\n') {
- outbyte('\r');
+ 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;
}
- outbyte( buffer[ count ] );
- }
-
- rw_args->bytes_moved = maximum;
+
+ BSP_uart_set_baud(BSPConsolePort, baud);
+
return 0;
}
-
+
/*
- * IO Control entry point
+ * BSP initialization
*/
-
-rtems_device_driver console_control(
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void * arg
-)
-{
- return RTEMS_SUCCESSFUL;
-}
-BSP_output_char_function_type BSP_output_char = outbyte;
-BSP_polling_getchar_function_type BSP_poll_char = BSP_wait_polled_input;
+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/i386ex/start/Makefile.in b/c/src/lib/libbsp/i386/i386ex/start/Makefile.in
index 985de4574c..aff674dbba 100644
--- a/c/src/lib/libbsp/i386/i386ex/start/Makefile.in
+++ b/c/src/lib/libbsp/i386/i386ex/start/Makefile.in
@@ -36,6 +36,7 @@ include $(RTEMS_ROOT)/make/leaf.cfg
ifeq ($(RTEMS_GAS_CODE16),yes)
DEFINES += -DNEXT_GAS
endif
+
CPPFLAGS +=
CFLAGS +=
diff --git a/c/src/lib/libbsp/i386/i386ex/startup/Makefile.in b/c/src/lib/libbsp/i386/i386ex/startup/Makefile.in
index 81809a2405..c12bd4662f 100644
--- a/c/src/lib/libbsp/i386/i386ex/startup/Makefile.in
+++ b/c/src/lib/libbsp/i386/i386ex/startup/Makefile.in
@@ -4,17 +4,15 @@
@SET_MAKE@
srcdir = @srcdir@
-VPATH = @srcdir@:@srcdir@/../../../shared
+VPATH = @srcdir@:@srcdir@/../../../shared:@srcdir@/../../shared/comm:@srcdir@/../../shared/irq:@srcdir@/../../shared/io
RTEMS_ROOT = @top_srcdir@
PROJECT_ROOT = @PROJECT_ROOT@
PGM=${ARCH}/startup.rel
-IMPORT_SRC=$(srcdir)/../../shared/irq/irq.c \
- $(srcdir)/../../shared/irq/irq_init.c $(srcdir)/../../shared/irq/irq_asm.s
-
# C source names, if any, go here -- minus the .c
-C_PIECES=bspclean bsplibc bsppost bspstart main sbrk irq irq_init
+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)
@@ -37,7 +35,8 @@ include $(RTEMS_ROOT)/make/leaf.cfg
#
#DEFINES += -DPRINTON
-DEFINES += -I$(srcdir)
+
+DEFINES += -I$(srcdir) -DBSP_IS_I386EX=1
CPPFLAGS +=
CFLAGS += -g
@@ -56,7 +55,9 @@ CLEAN_ADDITIONS +=
CLOBBER_ADDITIONS +=
preinstall:
- ${CP} ${IMPORT_SRC} .
+ $(INSTALL) ${IMPORT_SRC} .
+
+# ${CP} ${IMPORT_SRC} .
${PGM}: ${SRCS} ${OBJS}
$(make-rel)
diff --git a/c/src/lib/libbsp/i386/i386ex/timer/timer.c b/c/src/lib/libbsp/i386/i386ex/timer/timer.c
index 954bd7f6dd..208c5442a1 100644
--- a/c/src/lib/libbsp/i386/i386ex/timer/timer.c
+++ b/c/src/lib/libbsp/i386/i386ex/timer/timer.c
@@ -55,7 +55,7 @@ void TimerOn(const rtems_raw_irq_connect_data* used)
/*
* enable interrrupt at i8259 level
*/
- pc386_irq_enable_at_i8259s(used->idtIndex - PC386_IRQ_VECTOR_BASE);
+ BSP_irq_enable_at_i8259s(used->idtIndex - BSP_IRQ_VECTOR_BASE);
}
void TimerOff(const rtems_raw_irq_connect_data* used)
@@ -63,12 +63,12 @@ void TimerOff(const rtems_raw_irq_connect_data* used)
/*
* disable interrrupt at i8259 level
*/
- pc386_irq_disable_at_i8259s(used->idtIndex - PC386_IRQ_VECTOR_BASE);
+ 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 = {
- PC_386_RT_TIMER3 + PC386_IRQ_VECTOR_BASE,
+ BSP_RT_TIMER3 + BSP_IRQ_VECTOR_BASE,
timerisr,
TimerOn,
TimerOff,
diff --git a/c/src/lib/libbsp/i386/pc386/Makefile.in b/c/src/lib/libbsp/i386/pc386/Makefile.in
index 4862454e13..68582b5145 100644
--- a/c/src/lib/libbsp/i386/pc386/Makefile.in
+++ b/c/src/lib/libbsp/i386/pc386/Makefile.in
@@ -17,5 +17,5 @@ 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 tools start startup clock console timer pc386dev $(NETWORK) \
+SUB_DIRS=include tools start startup clock console timer $(NETWORK) \
wrapup
diff --git a/c/src/lib/libbsp/i386/pc386/clock/ckinit.c b/c/src/lib/libbsp/i386/pc386/clock/ckinit.c
index f3687d1e66..ee252a1e44 100644
--- a/c/src/lib/libbsp/i386/pc386/clock/ckinit.c
+++ b/c/src/lib/libbsp/i386/pc386/clock/ckinit.c
@@ -176,7 +176,7 @@ int clockIsOn(const rtems_irq_connect_data* unused)
return ((i8259s_cache & 0x1) == 0);
}
-static rtems_irq_connect_data clockIrqData = {PC_386_PERIODIC_TIMER,
+static rtems_irq_connect_data clockIrqData = {BSP_PERIODIC_TIMER,
clockIsr,
clockOn,
clockOff,
@@ -195,7 +195,7 @@ Clock_initialize(rtems_device_major_number major,
void *pargp)
{
- if (!pc386_install_rtems_irq_handler (&clockIrqData)) {
+ if (!BSP_install_rtems_irq_handler (&clockIrqData)) {
printk("Unable to initialize system clock\n");
rtems_fatal_error_occurred(1);
}
@@ -229,7 +229,7 @@ Clock_control(rtems_device_major_number major,
clockIsr();
else if (args->command == rtems_build_name('N', 'E', 'W', ' '))
{
- if (!pc386_install_rtems_irq_handler (&clockIrqData)) {
+ if (!BSP_install_rtems_irq_handler (&clockIrqData)) {
printk("Error installing clock interrupt handler!\n");
rtems_fatal_error_occurred(1);
}
@@ -241,7 +241,7 @@ Clock_control(rtems_device_major_number major,
void Clock_exit()
{
- pc386_remove_rtems_irq_handler (&clockIrqData);
+ BSP_remove_rtems_irq_handler (&clockIrqData);
}
/*-------------------------------------------------------------------------+
diff --git a/c/src/lib/libbsp/i386/pc386/console/console.c b/c/src/lib/libbsp/i386/pc386/console/console.c
index 23268bdd06..7a07a6ca3f 100644
--- a/c/src/lib/libbsp/i386/pc386/console/console.c
+++ b/c/src/lib/libbsp/i386/pc386/console/console.c
@@ -34,29 +34,34 @@
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
+#undef __assert
+void __assert (const char *file, int line, const char *msg);
#include <bsp.h>
#include <irq.h>
#include <rtems/libio.h>
#include <termios.h>
-#include <pc386uart.h>
+#include <uart.h>
#include <libcpu/cpuModel.h>
/*
* Possible value for console input/output :
- * PC386_CONSOLE_PORT_CONSOLE
- * PC386_UART_COM1
- * PC386_UART_COM2
+ * BSP_CONSOLE_PORT_CONSOLE
+ * BSP_UART_COM1
+ * BSP_UART_COM2
*/
/*
* Possible value for console input/output :
- * PC386_CONSOLE_PORT_CONSOLE
- * PC386_UART_COM1
- * PC386_UART_COM2
+ * BSP_CONSOLE_PORT_CONSOLE
+ * BSP_UART_COM1
+ * BSP_UART_COM2
*/
-int PC386ConsolePort = PC386_CONSOLE_PORT_CONSOLE;
+int BSPConsolePort = BSP_CONSOLE_PORT_CONSOLE;
+
+/* int BSPConsolePort = BSP_UART_COM2; */
+int BSPBaseBaud = 115200;
extern BSP_polling_getchar_function_type BSP_poll_char;
@@ -66,6 +71,7 @@ extern BSP_polling_getchar_function_type BSP_poll_char;
extern void _IBMPC_keyboard_isr(void);
extern rtems_boolean _IBMPC_scankey(char *); /* defined in 'inch.c' */
extern char BSP_wait_polled_input(void);
+extern void _IBMPC_initVideo(void);
static int conSetAttr(int minor, const struct termios *);
static void isr_on(const rtems_irq_connect_data *);
@@ -73,7 +79,7 @@ static void isr_off(const rtems_irq_connect_data *);
static int isr_is_on(const rtems_irq_connect_data *);
-static rtems_irq_connect_data console_isr_data = {PC_386_KEYBOARD,
+static rtems_irq_connect_data console_isr_data = {BSP_KEYBOARD,
_IBMPC_keyboard_isr,
isr_on,
isr_off,
@@ -94,28 +100,30 @@ isr_off(const rtems_irq_connect_data *unused)
static int
isr_is_on(const rtems_irq_connect_data *irq)
{
- return pc386_irq_enabled_at_i8259s(irq->name);
+ return BSP_irq_enabled_at_i8259s(irq->name);
}
void console_reserve_resources(rtems_configuration_table *conf)
{
- if(PC386ConsolePort != PC386_CONSOLE_PORT_CONSOLE)
+ if(BSPConsolePort != BSP_CONSOLE_PORT_CONSOLE)
{
rtems_termios_reserve_resources(conf, 1);
}
+
return;
}
-void __assert(const char *file, int line, const char *msg)
+void __assert (const char *file, int line, const char *msg)
{
- static char exit_msg[] = "EXECUTIVE SHUTDOWN! Any key to reboot...";
+ 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
*/
__rtems_close(2);
@@ -129,6 +137,7 @@ void __assert(const char *file, int line, const char *msg)
ch = BSP_poll_char();
printk("\n\n");
rtemsReboot();
+
}
@@ -149,11 +158,11 @@ console_initialize(rtems_device_major_number major,
* to be reinitialized.
*/
- if(PC386ConsolePort == PC386_CONSOLE_PORT_CONSOLE)
- {
+ if(BSPConsolePort == BSP_CONSOLE_PORT_CONSOLE)
+ {
/* Install keyboard interrupt handler */
- status = pc386_install_rtems_irq_handler(&console_isr_data);
+ status = BSP_install_rtems_irq_handler(&console_isr_data);
if (!status)
{
@@ -181,24 +190,24 @@ console_initialize(rtems_device_major_number major,
*/
/* 9600-8-N-1 */
- PC386_uart_init(PC386ConsolePort, 9600, 0);
+ BSP_uart_init(BSPConsolePort, 9600, 0);
/* Set interrupt handler */
- if(PC386ConsolePort == PC386_UART_COM1)
+ if(BSPConsolePort == BSP_UART_COM1)
{
- console_isr_data.name = PC386_UART_COM1_IRQ;
- console_isr_data.hdl = PC386_uart_termios_isr_com1;
+ console_isr_data.name = BSP_UART_COM1_IRQ;
+ console_isr_data.hdl = BSP_uart_termios_isr_com1;
}
else
{
- assert(PC386ConsolePort == PC386_UART_COM2);
- console_isr_data.name = PC386_UART_COM2_IRQ;
- console_isr_data.hdl = PC386_uart_termios_isr_com2;
+ assert(BSPConsolePort == BSP_UART_COM2);
+ console_isr_data.name = BSP_UART_COM2_IRQ;
+ console_isr_data.hdl = BSP_uart_termios_isr_com2;
}
- status = pc386_install_rtems_irq_handler(&console_isr_data);
+ status = BSP_install_rtems_irq_handler(&console_isr_data);
if (!status){
printk("Error installing serial console interrupt handler!\n");
@@ -214,7 +223,7 @@ console_initialize(rtems_device_major_number major,
rtems_fatal_error_occurred (status);
}
- if(PC386ConsolePort == PC386_UART_COM1)
+ if(BSPConsolePort == BSP_UART_COM1)
{
printk("Initialized console on port COM1 9600-8-N-1\n\n");
}
@@ -229,7 +238,7 @@ console_initialize(rtems_device_major_number major,
* using the video console for output while printf use serial line.
* This may be convenient to debug the serial line driver itself...
*/
- printk("Warning : This will be the last message displayed on console\n");
+ /* printk("Warning : This will be the last message displayed on console\n");*/
BSP_output_char = (BSP_output_char_function_type) BSP_output_char_via_serial;
BSP_poll_char = (BSP_polling_getchar_function_type) BSP_poll_char_via_serial;
#endif
@@ -242,7 +251,7 @@ static int console_open_count = 0;
static int console_last_close(int major, int minor, void *arg)
{
- pc386_remove_rtems_irq_handler (&console_isr_data);
+ BSP_remove_rtems_irq_handler (&console_isr_data);
return 0;
}
@@ -261,22 +270,22 @@ console_open(rtems_device_major_number major,
NULL, /* firstOpen */
console_last_close, /* lastClose */
NULL, /* pollRead */
- PC386_uart_termios_write_com1, /* write */
+ BSP_uart_termios_write_com1, /* write */
conSetAttr, /* setAttributes */
NULL, /* stopRemoteTx */
NULL, /* startRemoteTx */
1 /* outputUsesInterrupts */
};
- if(PC386ConsolePort == PC386_CONSOLE_PORT_CONSOLE)
+ if(BSPConsolePort == BSP_CONSOLE_PORT_CONSOLE)
{
++console_open_count;
return RTEMS_SUCCESSFUL;
}
- if(PC386ConsolePort == PC386_UART_COM2)
+ if(BSPConsolePort == BSP_UART_COM2)
{
- cb.write = PC386_uart_termios_write_com2;
+ cb.write = BSP_uart_termios_write_com2;
}
status = rtems_termios_open (major, minor, arg, &cb);
@@ -290,11 +299,11 @@ console_open(rtems_device_major_number major,
/*
* Pass data area info down to driver
*/
- PC386_uart_termios_set(PC386ConsolePort,
+ BSP_uart_termios_set(BSPConsolePort,
((rtems_libio_open_close_args_t *)arg)->iop->data1);
/* Enable interrupts on channel */
- PC386_uart_intr_ctrl(PC386ConsolePort, PC386_UART_INTR_CTRL_TERMIOS);
+ BSP_uart_intr_ctrl(BSPConsolePort, BSP_UART_INTR_CTRL_TERMIOS);
return RTEMS_SUCCESSFUL;
}
@@ -309,7 +318,7 @@ console_close(rtems_device_major_number major,
{
rtems_device_driver res = RTEMS_SUCCESSFUL;
- if(PC386ConsolePort != PC386_CONSOLE_PORT_CONSOLE)
+ if(BSPConsolePort != BSP_CONSOLE_PORT_CONSOLE)
{
res = rtems_termios_close (arg);
}
@@ -337,7 +346,7 @@ console_read(rtems_device_major_number major,
char *buffer = rw_args->buffer;
int count, maximum = rw_args->count;
- if(PC386ConsolePort != PC386_CONSOLE_PORT_CONSOLE)
+ if(BSPConsolePort != BSP_CONSOLE_PORT_CONSOLE)
{
return rtems_termios_read (arg);
}
@@ -382,7 +391,7 @@ console_write(rtems_device_major_number major,
char *buffer = rw_args->buffer;
int count, maximum = rw_args->count;
- if(PC386ConsolePort != PC386_CONSOLE_PORT_CONSOLE)
+ if(BSPConsolePort != BSP_CONSOLE_PORT_CONSOLE)
{
return rtems_termios_write (arg);
}
@@ -409,7 +418,7 @@ console_control(rtems_device_major_number major,
void * arg
)
{
- if(PC386ConsolePort != PC386_CONSOLE_PORT_CONSOLE)
+ if(BSPConsolePort != BSP_CONSOLE_PORT_CONSOLE)
{
return rtems_termios_ioctl (arg);
}
@@ -481,7 +490,7 @@ conSetAttr(int minor, const struct termios *t)
return 0;
}
- PC386_uart_set_baud(PC386ConsolePort, baud);
+ BSP_uart_set_baud(BSPConsolePort, baud);
return 0;
}
diff --git a/c/src/lib/libbsp/i386/pc386/include/bsp.h b/c/src/lib/libbsp/i386/pc386/include/bsp.h
index 002bf3b587..f18bdb375d 100644
--- a/c/src/lib/libbsp/i386/pc386/include/bsp.h
+++ b/c/src/lib/libbsp/i386/pc386/include/bsp.h
@@ -160,10 +160,10 @@ void printk(char *fmt, ...); /* from 'printk.c' */
void rtemsReboot(void); /* from 'exit.c' */
-/* Definitions for PC386ConsolePort */
-#define PC386_CONSOLE_PORT_CONSOLE (-1)
-#define PC386_CONSOLE_PORT_COM1 (PC386_UART_COM1)
-#define PC386_CONSOLE_PORT_COM2 (PC386_UART_COM2)
+/* Definitions for BSPConsolePort */
+#define BSP_CONSOLE_PORT_CONSOLE (-1)
+#define BSP_CONSOLE_PORT_COM1 (BSP_UART_COM1)
+#define BSP_CONSOLE_PORT_COM2 (BSP_UART_COM2)
/* GDB stub stuff */
void i386_stub_glue_init(int uart);
diff --git a/c/src/lib/libbsp/i386/pc386/start/Makefile.in b/c/src/lib/libbsp/i386/pc386/start/Makefile.in
index e085f50e5b..08007d952d 100644
--- a/c/src/lib/libbsp/i386/pc386/start/Makefile.in
+++ b/c/src/lib/libbsp/i386/pc386/start/Makefile.in
@@ -33,9 +33,9 @@ include $(RTEMS_ROOT)/make/leaf.cfg
# (OPTIONAL) Add local stuff here using +=
#
-ifeq ($(RTEMS_GAS_CODE16),yes)
+#ifeq ($(RTEMS_GAS_CODE16),yes)
DEFINES += -DNEXT_GAS
-endif
+#endif
CPPFLAGS +=
CFLAGS +=
diff --git a/c/src/lib/libbsp/i386/pc386/start/start16.s b/c/src/lib/libbsp/i386/pc386/start/start16.s
index d09430e0af..4b12408cd6 100644
--- a/c/src/lib/libbsp/i386/pc386/start/start16.s
+++ b/c/src/lib/libbsp/i386/pc386/start/start16.s
@@ -33,7 +33,7 @@
.set HDROFF, 0x24 # offset into bin2boot header of start32 addr
.set STACKOFF, 0x200-0x10 # offset to load into %esp, from start of image
-/* #define NEW_GAS*/
+ /* #define NEW_GAS */
/*----------------------------------------------------------------------------+
| CODE section
+----------------------------------------------------------------------------*/
diff --git a/c/src/lib/libbsp/i386/pc386/startup/Makefile.in b/c/src/lib/libbsp/i386/pc386/startup/Makefile.in
index b59323c6ff..c0da505e2d 100644
--- a/c/src/lib/libbsp/i386/pc386/startup/Makefile.in
+++ b/c/src/lib/libbsp/i386/pc386/startup/Makefile.in
@@ -4,14 +4,14 @@
@SET_MAKE@
srcdir = @srcdir@
-VPATH = @srcdir@:@srcdir@/../../../shared:@srcdir@/../../shared/irq
+VPATH = @srcdir@:@srcdir@/../../../shared:@srcdir@/../../shared/irq:@srcdir@/../../shared/comm:@srcdir@/../../shared/pci
RTEMS_ROOT = @top_srcdir@
PROJECT_ROOT = @PROJECT_ROOT@
PGM=${ARCH}/startup.rel
# C source names, if any, go here -- minus the .c
-C_PIECES=bsplibc bsppost bspstart exit irq irq_init main sbrk
+C_PIECES=bsplibc bsppost bspstart exit irq irq_init main sbrk i386-stub i386-stub-glue uart pcibios
C_FILES=$(C_PIECES:%=%.c)
C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
diff --git a/c/src/lib/libbsp/i386/pc386/startup/bspstart.c b/c/src/lib/libbsp/i386/pc386/startup/bspstart.c
index 5800cfad6e..a14ff0521f 100644
--- a/c/src/lib/libbsp/i386/pc386/startup/bspstart.c
+++ b/c/src/lib/libbsp/i386/pc386/startup/bspstart.c
@@ -146,6 +146,7 @@ void bsp_start( void )
/*
* Initialize printk channel
*/
+
_IBMPC_initVideo();
rtemsFreeMemStart = (rtems_unsigned32)&_end + _stack_size;
diff --git a/c/src/lib/libbsp/i386/pc386/startup/exit.c b/c/src/lib/libbsp/i386/pc386/startup/exit.c
index a9f11b9be4..c37888f003 100644
--- a/c/src/lib/libbsp/i386/pc386/startup/exit.c
+++ b/c/src/lib/libbsp/i386/pc386/startup/exit.c
@@ -35,7 +35,7 @@
#include <stdio.h>
#include <bsp.h>
#include <rtems/libio.h>
-#include <pc386uart.h>
+#include <uart.h>
void bsp_cleanup(void)
{
diff --git a/c/src/lib/libbsp/i386/pc386/startup/linkcmds b/c/src/lib/libbsp/i386/pc386/startup/linkcmds
index 5dd7a675a3..f66952b04c 100644
--- a/c/src/lib/libbsp/i386/pc386/startup/linkcmds
+++ b/c/src/lib/libbsp/i386/pc386/startup/linkcmds
@@ -62,7 +62,6 @@ SECTIONS
_rodata_start = . ;
*(.rodata)
- *(.gnu.linkonce.r*)
_erodata = ALIGN( 0x10 ) ;
_etext = ALIGN( 0x10 ) ;
diff --git a/c/src/lib/libbsp/i386/pc386/timer/timer.c b/c/src/lib/libbsp/i386/pc386/timer/timer.c
index 47e4894e00..4c83b309dd 100644
--- a/c/src/lib/libbsp/i386/pc386/timer/timer.c
+++ b/c/src/lib/libbsp/i386/pc386/timer/timer.c
@@ -167,7 +167,7 @@ timerOff(const rtems_raw_irq_connect_data* used)
/*
* disable interrrupt at i8259 level
*/
- pc386_irq_disable_at_i8259s(used->idtIndex - PC386_IRQ_VECTOR_BASE);
+ BSP_irq_disable_at_i8259s(used->idtIndex - BSP_IRQ_VECTOR_BASE);
/* reset timer mode to standard (DOS) value */
outport_byte(TIMER_MODE, TIMER_SEL0|TIMER_16BIT|TIMER_RATEGEN);
outport_byte(TIMER_CNTR0, 0);
@@ -185,16 +185,16 @@ timerOn(const rtems_raw_irq_connect_data* used)
/*
* enable interrrupt at i8259 level
*/
- pc386_irq_enable_at_i8259s(used->idtIndex - PC386_IRQ_VECTOR_BASE);
+ BSP_irq_enable_at_i8259s(used->idtIndex - BSP_IRQ_VECTOR_BASE);
}
static int
timerIsOn(const rtems_raw_irq_connect_data *used)
{
- return pc386_irq_enabled_at_i8259s(used->idtIndex - PC386_IRQ_VECTOR_BASE);}
+ return BSP_irq_enabled_at_i8259s(used->idtIndex - BSP_IRQ_VECTOR_BASE);}
static rtems_raw_irq_connect_data timer_raw_irq_data = {
- PC_386_PERIODIC_TIMER + PC386_IRQ_VECTOR_BASE,
+ BSP_PERIODIC_TIMER + BSP_IRQ_VECTOR_BASE,
timerisr,
timerOn,
timerOff,
diff --git a/c/src/lib/libbsp/i386/pc386/wrapup/Makefile.in b/c/src/lib/libbsp/i386/pc386/wrapup/Makefile.in
index 70515fdb8e..86462939cf 100644
--- a/c/src/lib/libbsp/i386/pc386/wrapup/Makefile.in
+++ b/c/src/lib/libbsp/i386/pc386/wrapup/Makefile.in
@@ -12,7 +12,7 @@ PROJECT_ROOT = @PROJECT_ROOT@
NETWORK_yes_V = network
NETWORK = $(NETWORK_$(HAS_NETWORKING)_V)
-BSP_PIECES=startup clock console timer pc386dev $(NETWORK)
+BSP_PIECES=startup clock console timer $(NETWORK)
GENERIC_PIECES=
# bummer; have to use $foreach since % pattern subst rules only replace 1x
diff --git a/c/src/lib/libbsp/i386/shared/Makefile.in b/c/src/lib/libbsp/i386/shared/Makefile.in
index 6fc07991ea..cee2697aae 100644
--- a/c/src/lib/libbsp/i386/shared/Makefile.in
+++ b/c/src/lib/libbsp/i386/shared/Makefile.in
@@ -12,5 +12,5 @@ include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg
include $(RTEMS_ROOT)/make/directory.cfg
# Descend into the $(RTEMS_BSP_FAMILY) directory
-SUB_DIRS=irq io
+SUB_DIRS=irq io comm pci
diff --git a/c/src/lib/libbsp/i386/shared/comm/GDB.HOWTO b/c/src/lib/libbsp/i386/shared/comm/GDB.HOWTO
new file mode 100644
index 0000000000..0fdfad02ea
--- /dev/null
+++ b/c/src/lib/libbsp/i386/shared/comm/GDB.HOWTO
@@ -0,0 +1,177 @@
+1. Add GDB initilization to your target's code:
+
+a) include file:
+
+#include <uart.h>
+
+b) declare this variable:
+
+extern int BSPConsolePort;
+
+c) To start-up GDB, run this:
+
+ /* Init GDB glue */
+
+ if(BSPConsolePort != BSP_UART_COM2)
+ {
+ /*
+ * If com2 is not used as console use it for
+ * debugging
+ */
+ i386_stub_glue_init(BSP_UART_COM2);
+ }
+ else
+ {
+ /* Otherwise use com1 */
+ i386_stub_glue_init(BSP_UART_COM1);
+ }
+
+ /* Init GDB stub itself */
+ set_debug_traps();
+
+ /*
+ * Init GDB break in capability,
+ * has to be called after
+ * set_debug_traps
+ */
+ i386_stub_glue_init_breakin();
+
+ /* Put breakpoint in */
+ breakpoint();
+
+d) This is all you need to do for the target.
+
+2. Edit cmds: specify path to current directory and device used for debugging
+ example of cmds is attached below. Make sure your paths are correct.
+3. type 'make'
+4. Boot o-pc386/<test>.exe on target computer, where <test> has the code from step 1. ( I modified and recompiled base_sp as the <test> )
+5. run 'i396-rtems-gdb --nx --command=./cmds o-pc386/<test>.coff
+
+=========================== example cmds ==============================
+dir /home/cross-19980908/tools/rtems-980923
+dir /home/cross-19980908/tools/rtems-980923/aclocal
+dir /home/cross-19980908/tools/rtems-980923/c
+dir /home/cross-19980908/tools/rtems-980923/c/build-tools
+dir /home/cross-19980908/tools/rtems-980923/c/build-tools/os
+dir /home/cross-19980908/tools/rtems-980923/c/build-tools/os/msdos
+dir /home/cross-19980908/tools/rtems-980923/c/build-tools/scripts
+dir /home/cross-19980908/tools/rtems-980923/c/build-tools/src
+dir /home/cross-19980908/tools/rtems-980923/c/src
+dir /home/cross-19980908/tools/rtems-980923/c/src/exec
+dir /home/cross-19980908/tools/rtems-980923/c/src/exec/posix
+dir /home/cross-19980908/tools/rtems-980923/c/src/exec/posix/base
+dir /home/cross-19980908/tools/rtems-980923/c/src/exec/posix/headers
+dir /home/cross-19980908/tools/rtems-980923/c/src/exec/posix/inline
+dir /home/cross-19980908/tools/rtems-980923/c/src/exec/posix/macros
+dir /home/cross-19980908/tools/rtems-980923/c/src/exec/posix/optman
+dir /home/cross-19980908/tools/rtems-980923/c/src/exec/posix/src
+dir /home/cross-19980908/tools/rtems-980923/c/src/exec/posix/sys
+dir /home/cross-19980908/tools/rtems-980923/c/src/exec/sapi
+dir /home/cross-19980908/tools/rtems-980923/c/src/exec/sapi/headers
+dir /home/cross-19980908/tools/rtems-980923/c/src/exec/sapi/src
+dir /home/cross-19980908/tools/rtems-980923/c/src/exec/sapi/inline
+dir /home/cross-19980908/tools/rtems-980923/c/src/exec/sapi/macros
+dir /home/cross-19980908/tools/rtems-980923/c/src/exec/sapi/optman
+dir /home/cross-19980908/tools/rtems-980923/c/src/exec/rtems
+dir /home/cross-19980908/tools/rtems-980923/c/src/exec/rtems/headers
+dir /home/cross-19980908/tools/rtems-980923/c/src/exec/rtems/src
+dir /home/cross-19980908/tools/rtems-980923/c/src/exec/rtems/inline
+dir /home/cross-19980908/tools/rtems-980923/c/src/exec/rtems/macros
+dir /home/cross-19980908/tools/rtems-980923/c/src/exec/rtems/optman
+dir /home/cross-19980908/tools/rtems-980923/c/src/exec/score
+dir /home/cross-19980908/tools/rtems-980923/c/src/exec/score/cpu
+dir /home/cross-19980908/tools/rtems-980923/c/src/exec/score/cpu/a29k
+dir /home/cross-19980908/tools/rtems-980923/c/src/exec/score/cpu/hppa1.1
+dir /home/cross-19980908/tools/rtems-980923/c/src/exec/score/cpu/i386
+dir /home/cross-19980908/tools/rtems-980923/c/src/exec/score/cpu/i960
+dir /home/cross-19980908/tools/rtems-980923/c/src/exec/score/cpu/m68k
+dir /home/cross-19980908/tools/rtems-980923/c/src/exec/score/cpu/mips64orion
+dir /home/cross-19980908/tools/rtems-980923/c/src/exec/score/cpu/no_cpu
+dir /home/cross-19980908/tools/rtems-980923/c/src/exec/score/cpu/powerpc
+dir /home/cross-19980908/tools/rtems-980923/c/src/exec/score/cpu/sh
+dir /home/cross-19980908/tools/rtems-980923/c/src/exec/score/cpu/sparc
+dir /home/cross-19980908/tools/rtems-980923/c/src/exec/score/cpu/unix
+dir /home/cross-19980908/tools/rtems-980923/c/src/exec/score/headers
+dir /home/cross-19980908/tools/rtems-980923/c/src/exec/score/inline
+dir /home/cross-19980908/tools/rtems-980923/c/src/exec/score/macros
+dir /home/cross-19980908/tools/rtems-980923/c/src/exec/score/src
+dir /home/cross-19980908/tools/rtems-980923/c/src/exec/score/tools
+dir /home/cross-19980908/tools/rtems-980923/c/src/exec/score/tools/generic
+dir /home/cross-19980908/tools/rtems-980923/c/src/exec/score/tools/unix
+dir /home/cross-19980908/tools/rtems-980923/c/src/exec/score/tools/hppa1.1
+dir /home/cross-19980908/tools/rtems-980923/c/src/exec/wrapup
+dir /home/cross-19980908/tools/rtems-980923/c/src/exec/wrapup/posix
+dir /home/cross-19980908/tools/rtems-980923/c/src/exec/wrapup/rtems
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/include
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/include/motorola
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/include/rtems++
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/include/sys
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/include/zilog
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libc
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libbsp
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libbsp/i386
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libbsp/i386/pc386
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libbsp/i386/pc386/clock
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libbsp/i386/pc386/console
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libbsp/i386/pc386/include
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libbsp/i386/pc386/start
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libbsp/i386/pc386/startup
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libbsp/i386/pc386/timer
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libbsp/i386/pc386/tools
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libbsp/i386/pc386/wrapup
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libbsp/i386/shared/comm
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libbsp/i386/shared/pci
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libcpu
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libcpu/hppa1.1
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libcpu/hppa1.1/clock
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libcpu/hppa1.1/include
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libcpu/hppa1.1/milli
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libcpu/hppa1.1/runway
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libcpu/hppa1.1/semaphore
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libcpu/hppa1.1/timer
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libcpu/m68k
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libcpu/m68k/m68040
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libcpu/m68k/m68040/fpsp
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libcpu/mips64orion
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libcpu/mips64orion/clock
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libcpu/mips64orion/include
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libcpu/mips64orion/timer
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libcpu/powerpc
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libcpu/powerpc/ppc403
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libcpu/powerpc/ppc403/clock
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libcpu/powerpc/ppc403/console
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libcpu/powerpc/ppc403/include
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libcpu/powerpc/ppc403/timer
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libcpu/powerpc/ppc403/vectors
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libcpu/sh
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libcpu/sh/sh7032
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libcpu/sh/sh7032/clock
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libcpu/sh/sh7032/null
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libcpu/sh/sh7032/console
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libcpu/sh/sh7032/include
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libcpu/sh/sh7032/timer
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libcpu/sparc
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libcpu/sparc/reg_win
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libnetworking
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libmisc
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libmisc/assoc
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libmisc/cpuuse
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libmisc/error
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libmisc/monitor
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libmisc/rtmonuse
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libmisc/stackchk
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/libmisc/wrapup
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/librtems++
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/start
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/start/a29k
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/start/i960
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/start/m68k
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/start/mips64orion
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/start/sh
+dir /home/cross-19980908/tools/rtems-980923/c/src/lib/wrapup
+dir /home/cross-19980908/tools/rtems-980923/c/src/tests
+dir /home/cross-19980908/tools/rtems-980923/c/src/tests/samples
+dir /home/cross-19980908/tools/rtems-980923/c/src/tests/samples/base_sp
+set remotebaud 38400
+target remote /dev/ttyS1
diff --git a/c/src/lib/libbsp/i386/shared/comm/Makefile.in b/c/src/lib/libbsp/i386/shared/comm/Makefile.in
new file mode 100644
index 0000000000..960dd1f2b4
--- /dev/null
+++ b/c/src/lib/libbsp/i386/shared/comm/Makefile.in
@@ -0,0 +1,33 @@
+#
+# $Id$
+#
+
+@SET_MAKE@
+srcdir = @srcdir@
+VPATH = @srcdir@
+RTEMS_ROOT = @top_srcdir@
+PROJECT_ROOT = @PROJECT_ROOT@
+
+H_FILES = $(srcdir)/uart.h
+
+#
+# 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 +=
+
+preinstall all: $(SRCS)
+ $(INSTALL) -m 444 $(SRCS) $(PROJECT_INCLUDE)
+
diff --git a/c/src/lib/libbsp/i386/shared/comm/i386-stub-glue.c b/c/src/lib/libbsp/i386/shared/comm/i386-stub-glue.c
new file mode 100644
index 0000000000..997237c1c2
--- /dev/null
+++ b/c/src/lib/libbsp/i386/shared/comm/i386-stub-glue.c
@@ -0,0 +1,194 @@
+/*
+ * This software is Copyright (C) 1998 by T.sqware - all rights limited
+ * It is provided in to the public domain "as is", can be freely modified
+ * as far as this copyight notice is kept unchanged, but does not imply
+ * an endorsement by T.sqware of the product in which it is included.
+ *
+ * $Id$
+ */
+
+#include <rtems/system.h>
+#include <rtems/score/cpu.h>
+#include <bsp.h>
+#include <irq.h>
+#include <uart.h>
+#include <assert.h>
+
+
+int putDebugChar(int ch); /* write a single character */
+int getDebugChar(void); /* read and return a single char */
+
+/* assign an exception handler */
+void exceptionHandler(int, void (*handler)(void));
+
+
+/* Current uart used by gdb stub */
+static int uart_current = 0;
+
+/*
+ * Initialize glue code linking i386-stub with the rest of
+ * the system
+ */
+void
+i386_stub_glue_init(int uart)
+{
+ assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
+
+ uart_current = uart;
+
+ BSP_uart_init(uart, 38400, 0);
+}
+
+void BSP_uart_on(const rtems_raw_irq_connect_data* used)
+{
+ BSP_irq_enable_at_i8259s(used->idtIndex - BSP_IRQ_VECTOR_BASE);
+}
+
+void BSP_uart_off(const rtems_raw_irq_connect_data* used)
+{
+ BSP_irq_disable_at_i8259s(used->idtIndex - BSP_IRQ_VECTOR_BASE);
+}
+
+int BSP_uart_isOn(const rtems_raw_irq_connect_data* used)
+{
+ return BSP_irq_enabled_at_i8259s(used->idtIndex - BSP_IRQ_VECTOR_BASE);
+}
+
+
+/*
+ * In order to have a possibility to break into
+ * running program, one has to call this function
+ */
+void i386_stub_glue_init_breakin(void)
+{
+ rtems_raw_irq_connect_data uart_raw_irq_data;
+
+ assert(uart_current == BSP_UART_COM1 || uart_current == BSP_UART_COM2);
+
+ if(uart_current == BSP_UART_COM1)
+ {
+ uart_raw_irq_data.idtIndex = BSP_UART_COM1_IRQ + BSP_IRQ_VECTOR_BASE;
+ }
+ else
+ {
+ uart_raw_irq_data.idtIndex = BSP_UART_COM2_IRQ + BSP_IRQ_VECTOR_BASE;
+ }
+
+ if(!i386_get_current_idt_entry(&uart_raw_irq_data))
+ {
+ printk("cannot get idt entry\n");
+ rtems_fatal_error_occurred(1);
+ }
+
+ if(!i386_delete_idt_entry(&uart_raw_irq_data))
+ {
+ printk("cannot delete idt entry\n");
+ rtems_fatal_error_occurred(1);
+ }
+
+ uart_raw_irq_data.on = BSP_uart_on;
+ uart_raw_irq_data.off = BSP_uart_off;
+ uart_raw_irq_data.isOn= BSP_uart_isOn;
+
+ /* Install ISR */
+ if(uart_current == BSP_UART_COM1)
+ {
+ uart_raw_irq_data.idtIndex = BSP_UART_COM1_IRQ + BSP_IRQ_VECTOR_BASE;
+ uart_raw_irq_data.hdl = BSP_uart_dbgisr_com1;
+ }
+ else
+ {
+ uart_raw_irq_data.idtIndex = BSP_UART_COM2_IRQ + BSP_IRQ_VECTOR_BASE;
+ uart_raw_irq_data.hdl = BSP_uart_dbgisr_com2;
+ }
+
+ if (!i386_set_idt_entry (&uart_raw_irq_data))
+ {
+ printk("raw exception handler connection failed\n");
+ rtems_fatal_error_occurred(1);
+ }
+
+ /* Enable interrupts */
+ BSP_uart_intr_ctrl(uart_current, BSP_UART_INTR_CTRL_GDB);
+
+ return;
+}
+
+
+int
+putDebugChar(int ch)
+{
+ assert(uart_current == BSP_UART_COM1 || uart_current == BSP_UART_COM2);
+
+ BSP_uart_polled_write(uart_current, ch);
+
+ return 1;
+}
+
+int getDebugChar(void)
+{
+ int val;
+
+ assert(uart_current == BSP_UART_COM1 || uart_current == BSP_UART_COM2);
+
+ val = BSP_uart_polled_read(uart_current);
+
+ return val;
+}
+
+static void nop(){}
+static int isOn() {return 1;}
+
+void exceptionHandler(int vector, void (*handler)(void))
+{
+ rtems_raw_irq_connect_data excep_raw_irq_data;
+
+ excep_raw_irq_data.idtIndex = vector;
+
+ if(!i386_get_current_idt_entry(&excep_raw_irq_data))
+ {
+ printk("cannot get idt entry\n");
+ rtems_fatal_error_occurred(1);
+ }
+
+ if(!i386_delete_idt_entry(&excep_raw_irq_data))
+ {
+ printk("cannot delete idt entry\n");
+ rtems_fatal_error_occurred(1);
+ }
+
+ excep_raw_irq_data.on = nop;
+ excep_raw_irq_data.off = nop;
+ excep_raw_irq_data.isOn = isOn;
+ excep_raw_irq_data.hdl = handler;
+
+ if (!i386_set_idt_entry (&excep_raw_irq_data)) {
+ printk("raw exception handler connection failed\n");
+ rtems_fatal_error_occurred(1);
+ }
+ return;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/c/src/lib/libbsp/i386/shared/comm/i386-stub.c b/c/src/lib/libbsp/i386/shared/comm/i386-stub.c
new file mode 100644
index 0000000000..d4fd60ad9b
--- /dev/null
+++ b/c/src/lib/libbsp/i386/shared/comm/i386-stub.c
@@ -0,0 +1,937 @@
+/*
+ * This is the gdb i386 remote debug stub from gdb 4.XX.
+ *
+ * $Id$
+ */
+
+/****************************************************************************
+
+ THIS SOFTWARE IS NOT COPYRIGHTED
+
+ HP offers the following for use in the public domain. HP makes no
+ warranty with regard to the software or it's performance and the
+ user accepts the software "AS IS" with all faults.
+
+ HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
+ TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+ ****************************************************************************/
+
+/****************************************************************************
+ * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $
+ *
+ * Module name: remcom.c $
+ * Revision: 1.34 $
+ * Date: 91/03/09 12:29:49 $
+ * Contributor: Lake Stevens Instrument Division$
+ *
+ * Description: low level support for gdb debugger. $
+ *
+ * Considerations: only works on target hardware $
+ *
+ * Written by: Glenn Engel $
+ * ModuleState: Experimental $
+ *
+ * NOTES: See Below $
+ *
+ * Modified for 386 by Jim Kingdon, Cygnus Support.
+ * Modified for RTEMS by Aleksey Romanov, Quality Quorum, Inc.
+ *
+ * To enable debugger support, two things need to happen. One, a
+ * call to set_debug_traps() is necessary in order to allow any breakpoints
+ * or error conditions to be properly intercepted and reported to gdb.
+ * Two, a breakpoint needs to be generated to begin communication. This
+ * is most easily accomplished by a call to breakpoint(). Breakpoint()
+ * simulates a breakpoint by executing a trap #1.
+ *
+ * The external function exceptionHandler() is
+ * used to attach a specific handler to a specific 386 vector number.
+ * It should use the same privilege level it runs at. It should
+ * install it as an interrupt gate so that interrupts are masked
+ * while the handler runs.
+ * Also, need to assign exceptionHook and oldExceptionHook.
+ *
+ * Because gdb will sometimes write to the stack area to execute function
+ * calls, this program cannot rely on using the supervisor stack so it
+ * uses it's own stack area reserved in the int array remcomStack.
+ *
+ *************
+ *
+ * The following gdb commands are supported:
+ *
+ * command function Return value
+ *
+ * g return the value of the CPU registers hex data or ENN
+ * G set the value of the CPU registers OK or ENN
+ *
+ * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN
+ * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN
+ *
+ * c Resume at current address SNN ( signal NN)
+ * cAA..AA Continue at address AA..AA SNN
+ *
+ * s Step one instruction SNN
+ * sAA..AA Step one instruction from AA..AA SNN
+ *
+ * k kill
+ *
+ * ? What was the last sigval ? SNN (signal NN)
+ *
+ * All commands and responses are sent with a packet which includes a
+ * checksum. A packet consists of
+ *
+ * $<packet info>#<checksum>.
+ *
+ * where
+ * <packet info> :: <characters representing the command or response>
+ * <checksum> :: < two hex digits computed as modulo 256 sum of <packetinfo>>
+ *
+ * When a packet is received, it is first acknowledged with either '+' or '-'.
+ * '+' indicates a successful transfer. '-' indicates a failed transfer.
+ *
+ * Example:
+ *
+ * Host: Reply:
+ * $m0,10#2a +$00010203040506070809101112131415#42
+ *
+ ****************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+
+/************************************************************************
+ *
+ * external low-level support routines
+ */
+extern int putDebugChar (int ch); /* write a single character */
+extern int getDebugChar (void); /* read and return a single char */
+
+/* assign an exception handler */
+extern void exceptionHandler (int, void (*handler) (void));
+
+/************************************************************************/
+/* BUFMAX defines the maximum number of characters in inbound/outbound buffers */
+/* at least NUMREGBYTES*2 are needed for register packets */
+#define BUFMAX 400
+
+static char initialized; /* boolean flag. != 0 means we've been initialized */
+
+int remote_debug;
+/* debug > 0 prints ill-formed commands in valid packets & checksum errors */
+
+void waitabit ();
+
+static const char hexchars[] = "0123456789abcdef";
+
+/* Number of bytes of registers. */
+#define NUMREGBYTES 64
+enum regnames
+ {
+ EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI,
+ PC /* also known as eip */ ,
+ PS /* also known as eflags */ ,
+ CS, SS, DS, ES, FS, GS
+ };
+
+/*
+ * these should not be static cuz they can be used outside this module
+ */
+int registers[NUMREGBYTES / 4];
+
+#define STACKSIZE 10000
+int remcomStack[STACKSIZE / sizeof (int)];
+static int *stackPtr = &remcomStack[STACKSIZE / sizeof (int) - 1];
+
+/*************************** ASSEMBLY CODE MACROS *************************/
+/* */
+
+extern void
+ return_to_prog (void);
+
+/* Restore the program's registers (including the stack pointer, which
+ means we get the right stack and don't have to worry about popping our
+ return address and any stack frames and so on) and return. */
+asm (".text");
+asm (".globl return_to_prog");
+asm ("return_to_prog:");
+asm (" movw registers+44, %ss");
+asm (" movl registers+16, %esp");
+asm (" movl registers+4, %ecx");
+asm (" movl registers+8, %edx");
+asm (" movl registers+12, %ebx");
+asm (" movl registers+20, %ebp");
+asm (" movl registers+24, %esi");
+asm (" movl registers+28, %edi");
+asm (" movw registers+48, %ds");
+asm (" movw registers+52, %es");
+asm (" movw registers+56, %fs");
+asm (" movw registers+60, %gs");
+asm (" movl registers+36, %eax");
+asm (" pushl %eax"); /* saved eflags */
+asm (" movl registers+40, %eax");
+asm (" pushl %eax"); /* saved cs */
+asm (" movl registers+32, %eax");
+asm (" pushl %eax"); /* saved eip */
+asm (" movl registers, %eax");
+/* use iret to restore pc and flags together so
+ that trace flag works right. */
+asm (" iret");
+
+#define BREAKPOINT() asm(" int $3");
+
+/* Put the error code here just in case the user cares. */
+int gdb_i386errcode;
+/* Likewise, the vector number here (since GDB only gets the signal
+ number through the usual means, and that's not very specific). */
+int gdb_i386vector = -1;
+
+/* GDB stores segment registers in 32-bit words (that's just the way
+ m-i386v.h is written). So zero the appropriate areas in registers. */
+#define SAVE_REGISTERS1() \
+ asm ("movl %eax, registers"); \
+ asm ("movl %ecx, registers+4"); \
+ asm ("movl %edx, registers+8"); \
+ asm ("movl %ebx, registers+12"); \
+ asm ("movl %ebp, registers+20"); \
+ asm ("movl %esi, registers+24"); \
+ asm ("movl %edi, registers+28"); \
+ asm ("movw $0, %ax"); \
+ asm ("movw %ds, registers+48"); \
+ asm ("movw %ax, registers+50"); \
+ asm ("movw %es, registers+52"); \
+ asm ("movw %ax, registers+54"); \
+ asm ("movw %fs, registers+56"); \
+ asm ("movw %ax, registers+58"); \
+ asm ("movw %gs, registers+60"); \
+ asm ("movw %ax, registers+62");
+#define SAVE_ERRCODE() \
+ asm ("popl %ebx"); \
+ asm ("movl %ebx, gdb_i386errcode");
+#define SAVE_REGISTERS2() \
+ asm ("popl %ebx"); /* old eip */ \
+ asm ("movl %ebx, registers+32"); \
+ asm ("popl %ebx"); /* old cs */ \
+ asm ("movl %ebx, registers+40"); \
+ asm ("movw %ax, registers+42"); \
+ asm ("popl %ebx"); /* old eflags */ \
+ asm ("movl %ebx, registers+36"); \
+ /* Now that we've done the pops, we can save the stack pointer."); */ \
+ asm ("movw %ss, registers+44"); \
+ asm ("movw %ax, registers+46"); \
+ asm ("movl %esp, registers+16");
+
+/* See if mem_fault_routine is set, if so just IRET to that address. */
+#define CHECK_FAULT() \
+ asm ("cmpl $0, mem_fault_routine"); \
+ asm ("jne mem_fault");
+
+asm (".text");
+asm ("mem_fault:");
+/* OK to clobber temp registers; we're just going to end up in set_mem_err. */
+/* Pop error code from the stack and save it. */
+asm (" popl %eax");
+asm (" movl %eax, gdb_i386errcode");
+
+asm (" popl %eax"); /* eip */
+/* We don't want to return there, we want to return to the function
+ pointed to by mem_fault_routine instead. */
+asm (" movl mem_fault_routine, %eax");
+asm (" popl %ecx"); /* cs (low 16 bits; junk in hi 16 bits). */
+asm (" popl %edx"); /* eflags */
+
+/* Remove this stack frame; when we do the iret, we will be going to
+ the start of a function, so we want the stack to look just like it
+ would after a "call" instruction. */
+asm (" leave");
+
+/* Push the stuff that iret wants. */
+asm (" pushl %edx"); /* eflags */
+asm (" pushl %ecx"); /* cs */
+asm (" pushl %eax"); /* eip */
+
+/* Zero mem_fault_routine. */
+asm (" movl $0, %eax");
+asm (" movl %eax, mem_fault_routine");
+
+asm ("iret");
+
+#define CALL_HOOK() asm("call _remcomHandler");
+
+/* This function is called when a i386 exception occurs. It saves
+ * all the cpu regs in the registers array, munges the stack a bit,
+ * and invokes an exception handler (remcom_handler).
+ *
+ * stack on entry: stack on exit:
+ * old eflags vector number
+ * old cs (zero-filled to 32 bits)
+ * old eip
+ *
+ */
+extern void _catchException3 ();
+asm (".text");
+asm (".globl _catchException3");
+asm ("_catchException3:");
+SAVE_REGISTERS1 ();
+SAVE_REGISTERS2 ();
+asm ("pushl $3");
+CALL_HOOK ();
+
+/* Same thing for exception 1. */
+extern void _catchException1 ();
+asm (".text");
+asm (".globl _catchException1");
+asm ("_catchException1:");
+SAVE_REGISTERS1 ();
+SAVE_REGISTERS2 ();
+asm ("pushl $1");
+CALL_HOOK ();
+
+/* Same thing for exception 0. */
+extern void _catchException0 ();
+asm (".text");
+asm (".globl _catchException0");
+asm ("_catchException0:");
+SAVE_REGISTERS1 ();
+SAVE_REGISTERS2 ();
+asm ("pushl $0");
+CALL_HOOK ();
+
+/* Same thing for exception 4. */
+extern void _catchException4 ();
+asm (".text");
+asm (".globl _catchException4");
+asm ("_catchException4:");
+SAVE_REGISTERS1 ();
+SAVE_REGISTERS2 ();
+asm ("pushl $4");
+CALL_HOOK ();
+
+/* Same thing for exception 5. */
+extern void _catchException5 ();
+asm (".text");
+asm (".globl _catchException5");
+asm ("_catchException5:");
+SAVE_REGISTERS1 ();
+SAVE_REGISTERS2 ();
+asm ("pushl $5");
+CALL_HOOK ();
+
+/* Same thing for exception 6. */
+extern void _catchException6 ();
+asm (".text");
+asm (".globl _catchException6");
+asm ("_catchException6:");
+SAVE_REGISTERS1 ();
+SAVE_REGISTERS2 ();
+asm ("pushl $6");
+CALL_HOOK ();
+
+/* Same thing for exception 7. */
+extern void _catchException7 ();
+asm (".text");
+asm (".globl _catchException7");
+asm ("_catchException7:");
+SAVE_REGISTERS1 ();
+SAVE_REGISTERS2 ();
+asm ("pushl $7");
+CALL_HOOK ();
+
+/* Same thing for exception 8. */
+extern void _catchException8 ();
+asm (".text");
+asm (".globl _catchException8");
+asm ("_catchException8:");
+SAVE_REGISTERS1 ();
+SAVE_ERRCODE ();
+SAVE_REGISTERS2 ();
+asm ("pushl $8");
+CALL_HOOK ();
+
+/* Same thing for exception 9. */
+extern void _catchException9 ();
+asm (".text");
+asm (".globl _catchException9");
+asm ("_catchException9:");
+SAVE_REGISTERS1 ();
+SAVE_REGISTERS2 ();
+asm ("pushl $9");
+CALL_HOOK ();
+
+/* Same thing for exception 10. */
+extern void _catchException10 ();
+asm (".text");
+asm (".globl _catchException10");
+asm ("_catchException10:");
+SAVE_REGISTERS1 ();
+SAVE_ERRCODE ();
+SAVE_REGISTERS2 ();
+asm ("pushl $10");
+CALL_HOOK ();
+
+/* Same thing for exception 12. */
+extern void _catchException12 ();
+asm (".text");
+asm (".globl _catchException12");
+asm ("_catchException12:");
+SAVE_REGISTERS1 ();
+SAVE_ERRCODE ();
+SAVE_REGISTERS2 ();
+asm ("pushl $12");
+CALL_HOOK ();
+
+/* Same thing for exception 16. */
+extern void _catchException16 ();
+asm (".text");
+asm (".globl _catchException16");
+asm ("_catchException16:");
+SAVE_REGISTERS1 ();
+SAVE_REGISTERS2 ();
+asm ("pushl $16");
+CALL_HOOK ();
+
+/* For 13, 11, and 14 we have to deal with the CHECK_FAULT stuff. */
+
+/* Same thing for exception 13. */
+extern void _catchException13 ();
+asm (".text");
+asm (".globl _catchException13");
+asm ("_catchException13:");
+CHECK_FAULT ();
+SAVE_REGISTERS1 ();
+SAVE_ERRCODE ();
+SAVE_REGISTERS2 ();
+asm ("pushl $13");
+CALL_HOOK ();
+
+/* Same thing for exception 11. */
+extern void _catchException11 ();
+asm (".text");
+asm (".globl _catchException11");
+asm ("_catchException11:");
+CHECK_FAULT ();
+SAVE_REGISTERS1 ();
+SAVE_ERRCODE ();
+SAVE_REGISTERS2 ();
+asm ("pushl $11");
+CALL_HOOK ();
+
+/* Same thing for exception 14. */
+extern void _catchException14 ();
+asm (".text");
+asm (".globl _catchException14");
+asm ("_catchException14:");
+CHECK_FAULT ();
+SAVE_REGISTERS1 ();
+SAVE_ERRCODE ();
+SAVE_REGISTERS2 ();
+asm ("pushl $14");
+CALL_HOOK ();
+
+/*
+ * remcomHandler is a front end for handle_exception. It moves the
+ * stack pointer into an area reserved for debugger use.
+ */
+asm ("_remcomHandler:");
+asm (" popl %eax"); /* pop off return address */
+asm (" popl %eax"); /* get the exception number */
+asm (" movl stackPtr, %esp"); /* move to remcom stack area */
+asm (" pushl %eax"); /* push exception onto stack */
+asm (" call handle_exception"); /* this never returns */
+
+void
+_returnFromException (void)
+{
+ return_to_prog ();
+}
+
+int
+hex (char ch)
+{
+ if ((ch >= 'a') && (ch <= 'f'))
+ return (ch - 'a' + 10);
+ if ((ch >= '0') && (ch <= '9'))
+ return (ch - '0');
+ if ((ch >= 'A') && (ch <= 'F'))
+ return (ch - 'A' + 10);
+ return (-1);
+}
+
+
+/* scan for the sequence $<data>#<checksum> */
+void
+getpacket (char *buffer)
+{
+ unsigned char checksum;
+ unsigned char xmitcsum;
+ int i;
+ int count;
+ char ch;
+
+ do
+ {
+ /* wait around for the start character, ignore all other characters */
+ while ((ch = (getDebugChar () & 0x7f)) != '$');
+ checksum = 0;
+ xmitcsum = -1;
+
+ count = 0;
+
+ /* now, read until a # or end of buffer is found */
+ while (count < BUFMAX)
+ {
+ ch = getDebugChar () & 0x7f;
+ if (ch == '#')
+ break;
+ checksum = checksum + ch;
+ buffer[count] = ch;
+ count = count + 1;
+ }
+ buffer[count] = 0;
+
+ if (ch == '#')
+ {
+ xmitcsum = hex (getDebugChar () & 0x7f) << 4;
+ xmitcsum += hex (getDebugChar () & 0x7f);
+ if ((remote_debug) && (checksum != xmitcsum))
+ {
+ fprintf (stderr, "bad checksum. My count = 0x%x, sent=0x%x. buf=%s\n",
+ checksum, xmitcsum, buffer);
+ }
+
+ if (checksum != xmitcsum)
+ putDebugChar ('-'); /* failed checksum */
+ else
+ {
+ putDebugChar ('+'); /* successful transfer */
+ /* if a sequence char is present, reply the sequence ID */
+ if (buffer[2] == ':')
+ {
+ putDebugChar (buffer[0]);
+ putDebugChar (buffer[1]);
+ /* remove sequence chars from buffer */
+ count = strlen (buffer);
+ for (i = 3; i <= count; i++)
+ buffer[i - 3] = buffer[i];
+ }
+ }
+ }
+ }
+ while (checksum != xmitcsum);
+
+}
+
+/* send the packet in buffer. */
+
+
+void
+putpacket (char *buffer)
+{
+ unsigned char checksum;
+ int count;
+ char ch;
+
+ /* $<packet info>#<checksum>. */
+ do
+ {
+ putDebugChar ('$');
+ checksum = 0;
+ count = 0;
+
+ while ((ch = buffer[count]))
+ {
+ if (!putDebugChar (ch))
+ return;
+ checksum += ch;
+ count += 1;
+ }
+
+ putDebugChar ('#');
+ putDebugChar (hexchars[checksum >> 4]);
+ putDebugChar (hexchars[checksum % 16]);
+
+ }
+ while ((getDebugChar () & 0x7f) != '+');
+
+}
+
+char remcomInBuffer[BUFMAX];
+char remcomOutBuffer[BUFMAX];
+static short error;
+
+void
+debug_error (format, parm)
+ char *format;
+ char *parm;
+{
+ if (remote_debug)
+ fprintf (stderr, format, parm);
+}
+
+/* Address of a routine to RTE to if we get a memory fault. */
+static void (*volatile mem_fault_routine) (void) = NULL;
+
+/* Indicate to caller of mem2hex or hex2mem that there has been an
+ error. */
+static volatile int mem_err = 0;
+
+void
+set_mem_err (void)
+{
+ mem_err = 1;
+}
+
+/* These are separate functions so that they are so short and sweet
+ that the compiler won't save any registers (if there is a fault
+ to mem_fault, they won't get restored, so there better not be any
+ saved). */
+int
+get_char (char *addr)
+{
+ return *addr;
+}
+
+void
+set_char (char *addr, int val)
+{
+ *addr = val;
+}
+
+/* convert the memory pointed to by mem into hex, placing result in buf */
+/* return a pointer to the last char put in buf (null) */
+/* If MAY_FAULT is non-zero, then we should set mem_err in response to
+ a fault; if zero treat a fault like any other fault in the stub. */
+char *
+mem2hex (char *mem, char *buf, int count, int may_fault)
+{
+ int i;
+ unsigned char ch;
+
+ if (may_fault)
+ mem_fault_routine = set_mem_err;
+ for (i = 0; i < count; i++)
+ {
+ ch = get_char (mem++);
+ if (may_fault && mem_err)
+ return (buf);
+ *buf++ = hexchars[ch >> 4];
+ *buf++ = hexchars[ch % 16];
+ }
+ *buf = 0;
+ if (may_fault)
+ mem_fault_routine = NULL;
+ return (buf);
+}
+
+/* convert the hex array pointed to by buf into binary to be placed in mem */
+/* return a pointer to the character AFTER the last byte written */
+char *
+hex2mem (char *buf, char *mem, int count, int may_fault)
+{
+ int i;
+ unsigned char ch;
+
+ if (may_fault)
+ mem_fault_routine = set_mem_err;
+ for (i = 0; i < count; i++)
+ {
+ ch = hex (*buf++) << 4;
+ ch = ch + hex (*buf++);
+ set_char (mem++, ch);
+ if (may_fault && mem_err)
+ return (mem);
+ }
+ if (may_fault)
+ mem_fault_routine = NULL;
+ return (mem);
+}
+
+/* this function takes the 386 exception vector and attempts to
+ translate this number into a unix compatible signal value */
+int
+computeSignal (int exceptionVector)
+{
+ int sigval;
+ switch (exceptionVector)
+ {
+ case 0:
+ sigval = 8;
+ break; /* divide by zero */
+ case 1:
+ sigval = 5;
+ break; /* debug exception */
+ case 3:
+ sigval = 5;
+ break; /* breakpoint */
+ case 4:
+ sigval = 16;
+ break; /* into instruction (overflow) */
+ case 5:
+ sigval = 16;
+ break; /* bound instruction */
+ case 6:
+ sigval = 4;
+ break; /* Invalid opcode */
+ case 7:
+ sigval = 8;
+ break; /* coprocessor not available */
+ case 8:
+ sigval = 7;
+ break; /* double fault */
+ case 9:
+ sigval = 11;
+ break; /* coprocessor segment overrun */
+ case 10:
+ sigval = 11;
+ break; /* Invalid TSS */
+ case 11:
+ sigval = 11;
+ break; /* Segment not present */
+ case 12:
+ sigval = 11;
+ break; /* stack exception */
+ case 13:
+ sigval = 11;
+ break; /* general protection */
+ case 14:
+ sigval = 11;
+ break; /* page fault */
+ case 16:
+ sigval = 7;
+ break; /* coprocessor error */
+ default:
+ sigval = 7; /* "software generated" */
+ }
+ return (sigval);
+}
+
+/**********************************************/
+/* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */
+/* RETURN NUMBER OF CHARS PROCESSED */
+/**********************************************/
+int
+hexToInt (char **ptr, int *intValue)
+{
+ int numChars = 0;
+ int hexValue;
+
+ *intValue = 0;
+
+ while (**ptr)
+ {
+ hexValue = hex (**ptr);
+ if (hexValue >= 0)
+ {
+ *intValue = (*intValue << 4) | hexValue;
+ numChars++;
+ }
+ else
+ break;
+
+ (*ptr)++;
+ }
+
+ return (numChars);
+}
+
+/*
+ * This function does all command procesing for interfacing to gdb.
+ */
+void
+handle_exception (int exceptionVector)
+{
+ int sigval;
+ int addr, length;
+ char *ptr;
+ int newPC;
+
+ gdb_i386vector = exceptionVector;
+
+ if (remote_debug)
+ printf ("vector=%d, sr=0x%x, pc=0x%x\n",
+ exceptionVector,
+ registers[PS],
+ registers[PC]);
+
+ /* reply to host that an exception has occurred */
+ sigval = computeSignal (exceptionVector);
+ remcomOutBuffer[0] = 'S';
+ remcomOutBuffer[1] = hexchars[sigval >> 4];
+ remcomOutBuffer[2] = hexchars[sigval % 16];
+ remcomOutBuffer[3] = 0;
+
+ putpacket (remcomOutBuffer);
+
+ while (1 == 1)
+ {
+ error = 0;
+ remcomOutBuffer[0] = 0;
+ getpacket (remcomInBuffer);
+ switch (remcomInBuffer[0])
+ {
+ case '?':
+ remcomOutBuffer[0] = 'S';
+ remcomOutBuffer[1] = hexchars[sigval >> 4];
+ remcomOutBuffer[2] = hexchars[sigval % 16];
+ remcomOutBuffer[3] = 0;
+ break;
+ case 'd':
+ remote_debug = !(remote_debug); /* toggle debug flag */
+ break;
+ case 'g': /* return the value of the CPU registers */
+ mem2hex ((char *) registers, remcomOutBuffer, NUMREGBYTES, 0);
+ break;
+ case 'G': /* set the value of the CPU registers - return OK */
+ hex2mem (&remcomInBuffer[1], (char *) registers, NUMREGBYTES, 0);
+ strcpy (remcomOutBuffer, "OK");
+ break;
+
+ /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */
+ case 'm':
+ /* TRY TO READ %x,%x. IF SUCCEED, SET PTR = 0 */
+ ptr = &remcomInBuffer[1];
+ if (hexToInt (&ptr, &addr))
+ if (*(ptr++) == ',')
+ if (hexToInt (&ptr, &length))
+ {
+ ptr = 0;
+ mem_err = 0;
+ mem2hex ((char *) addr, remcomOutBuffer, length, 1);
+ if (mem_err)
+ {
+ strcpy (remcomOutBuffer, "E03");
+ debug_error ("memory fault");
+ }
+ }
+
+ if (ptr)
+ {
+ strcpy (remcomOutBuffer, "E01");
+ debug_error ("malformed read memory command: %s", remcomInBuffer);
+ }
+ break;
+
+ /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
+ case 'M':
+ /* TRY TO READ '%x,%x:'. IF SUCCEED, SET PTR = 0 */
+ ptr = &remcomInBuffer[1];
+ if (hexToInt (&ptr, &addr))
+ if (*(ptr++) == ',')
+ if (hexToInt (&ptr, &length))
+ if (*(ptr++) == ':')
+ {
+ mem_err = 0;
+ hex2mem (ptr, (char *) addr, length, 1);
+
+ if (mem_err)
+ {
+ strcpy (remcomOutBuffer, "E03");
+ debug_error ("memory fault");
+ }
+ else
+ {
+ strcpy (remcomOutBuffer, "OK");
+ }
+
+ ptr = 0;
+ }
+ if (ptr)
+ {
+ strcpy (remcomOutBuffer, "E02");
+ debug_error ("malformed write memory command: %s", remcomInBuffer);
+ }
+ break;
+
+ /* cAA..AA Continue at address AA..AA(optional) */
+ /* sAA..AA Step one instruction from AA..AA(optional) */
+ case 'c':
+ case 's':
+ /* try to read optional parameter, pc unchanged if no parm */
+ ptr = &remcomInBuffer[1];
+ if (hexToInt (&ptr, &addr))
+ registers[PC] = addr;
+
+ newPC = registers[PC];
+
+ /* clear the trace bit */
+ registers[PS] &= 0xfffffeff;
+
+ /* set the trace bit if we're stepping */
+ if (remcomInBuffer[0] == 's')
+ registers[PS] |= 0x100;
+
+ _returnFromException (); /* this is a jump */
+
+ break;
+
+ /* kill the program */
+ case 'k': /* do nothing */
+ break;
+ } /* switch */
+
+ /* reply to the request */
+ putpacket (remcomOutBuffer);
+ }
+}
+
+/* this function is used to set up exception handlers for tracing and
+ breakpoints */
+void
+set_debug_traps (void)
+{
+ extern void remcomHandler ();
+
+ stackPtr = &remcomStack[STACKSIZE / sizeof (int) - 1];
+
+ exceptionHandler (0, _catchException0);
+ exceptionHandler (1, _catchException1);
+ exceptionHandler (3, _catchException3);
+ exceptionHandler (4, _catchException4);
+ exceptionHandler (5, _catchException5);
+ exceptionHandler (6, _catchException6);
+ exceptionHandler (7, _catchException7);
+ exceptionHandler (8, _catchException8);
+ exceptionHandler (9, _catchException9);
+ exceptionHandler (10, _catchException10);
+ exceptionHandler (11, _catchException11);
+ exceptionHandler (12, _catchException12);
+ exceptionHandler (13, _catchException13);
+ exceptionHandler (14, _catchException14);
+ exceptionHandler (16, _catchException16);
+
+ /* In case GDB is started before us, ack any packets (presumably
+ "$?#xx") sitting there. */
+ putDebugChar ('+');
+
+ initialized = 1;
+
+}
+
+/* This function will generate a breakpoint exception. It is used at the
+ beginning of a program to sync up with a debugger and can be used
+ otherwise as a quick means to stop program execution and "break" into
+ the debugger. */
+
+void
+breakpoint (void)
+{
+ if (initialized)
+ {
+ BREAKPOINT ();
+ }
+ waitabit ();
+}
+
+int waitlimit = 1000000;
+
+void
+waitabit (void)
+{
+ int i;
+ for (i = 0; i < waitlimit; i++);
+}
+
+
+
+
+
diff --git a/c/src/lib/libbsp/i386/shared/comm/uart.c b/c/src/lib/libbsp/i386/shared/comm/uart.c
new file mode 100644
index 0000000000..5d258d7232
--- /dev/null
+++ b/c/src/lib/libbsp/i386/shared/comm/uart.c
@@ -0,0 +1,935 @@
+/*
+ * This software is Copyright (C) 1998 by T.sqware - all rights limited
+ * It is provided in to the public domain "as is", can be freely modified
+ * as far as this copyight notice is kept unchanged, but does not imply
+ * an endorsement by T.sqware of the product in which it is included.
+ *
+ * $Id$
+ */
+
+#include <bsp.h>
+#include <irq.h>
+#include <uart.h>
+#include <rtems/libio.h>
+#include <assert.h>
+
+/*
+ * Basic 16552 driver
+ */
+
+struct uart_data
+{
+ int hwFlow;
+ int baud;
+};
+
+static struct uart_data uart_data[2];
+
+/*
+ * Macros to read/wirte register of uart, if configuration is
+ * different just rewrite these macros
+ */
+
+static inline unsigned char
+uread(int uart, unsigned int reg)
+{
+ register unsigned char val;
+
+ if(uart == 0)
+ {
+ i386_inport_byte(COM1_BASE_IO+reg, val);
+ }
+ else
+ {
+ i386_inport_byte(COM2_BASE_IO+reg, val);
+ }
+
+ return val;
+}
+
+static inline void
+uwrite(int uart, int reg, unsigned int val)
+{
+ if(uart == 0)
+ {
+ i386_outport_byte(COM1_BASE_IO+reg, val);
+ }
+ else
+ {
+ i386_outport_byte(COM2_BASE_IO+reg, val);
+ }
+}
+
+#ifdef UARTDEBUG
+ static void
+uartError(int uart)
+{
+ unsigned char uartStatus, dummy;
+
+ uartStatus = uread(uart, LSR);
+ dummy = uread(uart, RBR);
+
+ if (uartStatus & OE)
+ printk("********* Over run Error **********\n");
+ if (uartStatus & PE)
+ printk("********* Parity Error **********\n");
+ if (uartStatus & FE)
+ printk("********* Framing Error **********\n");
+ if (uartStatus & BI)
+ printk("********* Parity Error **********\n");
+ if (uartStatus & ERFIFO)
+ printk("********* Error receive Fifo **********\n");
+
+}
+#else
+inline void uartError(int uart)
+{
+ unsigned char uartStatus;
+
+ uartStatus = uread(uart, LSR);
+ uartStatus = uread(uart, RBR);
+}
+#endif
+
+/*
+ * Uart initialization, it is hardcoded to 8 bit, no parity,
+ * one stop bit, FIFO, things to be changed
+ * are baud rate and nad hw flow control,
+ * and longest rx fifo setting
+ */
+void
+BSP_uart_init(int uart, int baud, int hwFlow)
+{
+ unsigned char tmp;
+
+ /* Sanity check */
+ assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
+
+ switch(baud)
+ {
+ case 50:
+ case 75:
+ case 110:
+ case 134:
+ case 300:
+ case 600:
+ case 1200:
+ case 2400:
+ case 9600:
+ case 19200:
+ case 38400:
+ case 57600:
+ case 115200:
+ break;
+ default:
+ assert(0);
+ return;
+ }
+
+ /* Set DLAB bit to 1 */
+ uwrite(uart, LCR, DLAB);
+
+ /* Set baud rate */
+ uwrite(uart, DLL, (BSPBaseBaud/baud) & 0xff);
+ uwrite(uart, DLM, ((BSPBaseBaud/baud) >> 8) & 0xff);
+
+ /* 8-bit, no parity , 1 stop */
+ uwrite(uart, LCR, CHR_8_BITS);
+
+
+ /* Set DTR, RTS and OUT2 high */
+ uwrite(uart, MCR, DTR | RTS | OUT_2);
+
+ /* Enable FIFO */
+ uwrite(uart, FCR, FIFO_EN | XMIT_RESET | RCV_RESET | RECEIVE_FIFO_TRIGGER12);
+
+ /* Disable Interrupts */
+ uwrite(uart, IER, 0);
+
+ /* Read status to clear them */
+ tmp = uread(uart, LSR);
+ tmp = uread(uart, RBR);
+ tmp = uread(uart, MSR);
+
+ /* Remember state */
+ uart_data[uart].hwFlow = hwFlow;
+ uart_data[uart].baud = baud;
+ return;
+}
+
+/*
+ * Set baud
+ */
+void
+BSP_uart_set_baud(int uart, int baud)
+{
+ unsigned char mcr, ier;
+
+ /* Sanity check */
+ assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
+
+ /*
+ * This function may be called whenever TERMIOS parameters
+ * are changed, so we have to make sire that baud change is
+ * indeed required
+ */
+
+ if(baud == uart_data[uart].baud)
+ {
+ return;
+ }
+
+ mcr = uread(uart, MCR);
+ ier = uread(uart, IER);
+
+ BSP_uart_init(uart, baud, uart_data[uart].hwFlow);
+
+ uwrite(uart, MCR, mcr);
+ uwrite(uart, IER, ier);
+
+ return;
+}
+
+/*
+ * Enable/disable interrupts
+ */
+void
+BSP_uart_intr_ctrl(int uart, int cmd)
+{
+
+ assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
+
+ switch(cmd)
+ {
+ case BSP_UART_INTR_CTRL_DISABLE:
+ uwrite(uart, IER, INTERRUPT_DISABLE);
+ break;
+ case BSP_UART_INTR_CTRL_ENABLE:
+ if(uart_data[uart].hwFlow)
+ {
+ uwrite(uart, IER,
+ (RECEIVE_ENABLE |
+ TRANSMIT_ENABLE |
+ RECEIVER_LINE_ST_ENABLE |
+ MODEM_ENABLE
+ )
+ );
+ }
+ else
+ {
+ uwrite(uart, IER,
+ (RECEIVE_ENABLE |
+ TRANSMIT_ENABLE |
+ RECEIVER_LINE_ST_ENABLE
+ )
+ );
+ }
+ break;
+ case BSP_UART_INTR_CTRL_TERMIOS:
+ if(uart_data[uart].hwFlow)
+ {
+ uwrite(uart, IER,
+ (RECEIVE_ENABLE |
+ RECEIVER_LINE_ST_ENABLE |
+ MODEM_ENABLE
+ )
+ );
+ }
+ else
+ {
+ uwrite(uart, IER,
+ (RECEIVE_ENABLE |
+ RECEIVER_LINE_ST_ENABLE
+ )
+ );
+ }
+ break;
+ case BSP_UART_INTR_CTRL_GDB:
+ uwrite(uart, IER, RECEIVE_ENABLE);
+ break;
+ default:
+ assert(0);
+ break;
+ }
+
+ return;
+}
+
+void
+BSP_uart_throttle(int uart)
+{
+ unsigned int mcr;
+
+ assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
+
+ if(!uart_data[uart].hwFlow)
+ {
+ /* Should not happen */
+ assert(0);
+ return;
+ }
+ mcr = uread (uart, MCR);
+ /* RTS down */
+ mcr &= ~RTS;
+ uwrite(uart, MCR, mcr);
+
+ return;
+}
+
+void
+BSP_uart_unthrottle(int uart)
+{
+ unsigned int mcr;
+
+ assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
+
+ if(!uart_data[uart].hwFlow)
+ {
+ /* Should not happen */
+ assert(0);
+ return;
+ }
+ mcr = uread (uart, MCR);
+ /* RTS up */
+ mcr |= RTS;
+ uwrite(uart, MCR, mcr);
+
+ return;
+}
+
+/*
+ * Status function, -1 if error
+ * detected, 0 if no received chars available,
+ * 1 if received char available, 2 if break
+ * is detected, it will eat break and error
+ * chars. It ignores overruns - we cannot do
+ * anything about - it execpt count statistics
+ * and we are not counting it.
+ */
+int
+BSP_uart_polled_status(int uart)
+{
+ unsigned char val;
+
+ assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
+
+ val = uread(uart, LSR);
+
+ if(val & BI)
+ {
+ /* BREAK found, eat character */
+ uread(uart, RBR);
+ return BSP_UART_STATUS_BREAK;
+ }
+
+ if((val & (DR | OE | FE)) == 1)
+ {
+ /* No error, character present */
+ return BSP_UART_STATUS_CHAR;
+ }
+
+ if((val & (DR | OE | FE)) == 0)
+ {
+ /* Nothing */
+ return BSP_UART_STATUS_NOCHAR;
+ }
+
+ /*
+ * Framing or parity error
+ * eat character
+ */
+ uread(uart, RBR);
+
+ return BSP_UART_STATUS_ERROR;
+}
+
+
+/*
+ * Polled mode write function
+ */
+void
+BSP_uart_polled_write(int uart, int val)
+{
+ unsigned char val1;
+
+ /* Sanity check */
+ assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
+
+ for(;;)
+ {
+ if((val1=uread(uart, LSR)) & THRE)
+ {
+ break;
+ }
+ }
+
+ if(uart_data[uart].hwFlow)
+ {
+ for(;;)
+ {
+ if(uread(uart, MSR) & CTS)
+ {
+ break;
+ }
+ }
+ }
+
+ uwrite(uart, THR, val & 0xff);
+
+ return;
+}
+
+void
+BSP_output_char_via_serial(int val)
+{
+ BSP_uart_polled_write(BSPConsolePort, val);
+ if (val == '\n') BSP_uart_polled_write(BSPConsolePort,'\r');
+}
+
+/*
+ * Polled mode read function
+ */
+int
+BSP_uart_polled_read(int uart)
+{
+ unsigned char val;
+
+ assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
+
+ for(;;)
+ {
+ if(uread(uart, LSR) & DR)
+ {
+ break;
+ }
+ }
+
+ val = uread(uart, RBR);
+
+ return (int)(val & 0xff);
+}
+
+unsigned
+BSP_poll_char_via_serial()
+{
+ return BSP_uart_polled_read(BSPConsolePort);
+}
+
+
+/* ================ Termios support =================*/
+
+static volatile int termios_stopped_com1 = 0;
+static volatile int termios_tx_active_com1 = 0;
+static void* termios_ttyp_com1 = NULL;
+static char termios_tx_hold_com1 = 0;
+static volatile char termios_tx_hold_valid_com1 = 0;
+
+static volatile int termios_stopped_com2 = 0;
+static volatile int termios_tx_active_com2 = 0;
+static void* termios_ttyp_com2 = NULL;
+static char termios_tx_hold_com2 = 0;
+static volatile char termios_tx_hold_valid_com2 = 0;
+
+/*
+ * Set channel parameters
+ */
+void
+BSP_uart_termios_set(int uart, void *ttyp)
+{
+ unsigned char val;
+ assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
+
+ if(uart == BSP_UART_COM1)
+ {
+ if(uart_data[uart].hwFlow)
+ {
+ val = uread(uart, MSR);
+
+ termios_stopped_com1 = (val & CTS) ? 0 : 1;
+ }
+ else
+ {
+ termios_stopped_com1 = 0;
+ }
+ termios_tx_active_com1 = 0;
+ termios_ttyp_com1 = ttyp;
+ termios_tx_hold_com1 = 0;
+ termios_tx_hold_valid_com1 = 0;
+ }
+ else
+ {
+ if(uart_data[uart].hwFlow)
+ {
+ val = uread(uart, MSR);
+
+ termios_stopped_com2 = (val & CTS) ? 0 : 1;
+ }
+ else
+ {
+ termios_stopped_com2 = 0;
+ }
+ termios_tx_active_com2 = 0;
+ termios_ttyp_com2 = ttyp;
+ termios_tx_hold_com2 = 0;
+ termios_tx_hold_valid_com2 = 0;
+ }
+
+ return;
+}
+
+int
+BSP_uart_termios_write_com1(int minor, const char *buf, int len)
+{
+ assert(buf != NULL);
+
+ if(len <= 0)
+ {
+ return 0;
+ }
+
+ /* If there TX buffer is busy - something is royally screwed up */
+ assert((uread(BSP_UART_COM1, LSR) & THRE) != 0);
+
+ if(termios_stopped_com1)
+ {
+ /* CTS low */
+ termios_tx_hold_com1 = *buf;
+ termios_tx_hold_valid_com1 = 1;
+ return 0;
+ }
+
+ /* Write character */
+ uwrite(BSP_UART_COM1, THR, *buf & 0xff);
+
+ /* Enable interrupts if necessary */
+ if(!termios_tx_active_com1 && uart_data[BSP_UART_COM1].hwFlow)
+ {
+ termios_tx_active_com1 = 1;
+ uwrite(BSP_UART_COM1, IER,
+ (RECEIVE_ENABLE |
+ TRANSMIT_ENABLE |
+ RECEIVER_LINE_ST_ENABLE |
+ MODEM_ENABLE
+ )
+ );
+ }
+ else if(!termios_tx_active_com1)
+ {
+ termios_tx_active_com1 = 1;
+ uwrite(BSP_UART_COM1, IER,
+ (RECEIVE_ENABLE |
+ TRANSMIT_ENABLE |
+ RECEIVER_LINE_ST_ENABLE
+ )
+ );
+ }
+
+ return 0;
+}
+
+int
+BSP_uart_termios_write_com2(int minor, const char *buf, int len)
+{
+ assert(buf != NULL);
+
+ if(len <= 0)
+ {
+ return 0;
+ }
+
+
+ /* If there TX buffer is busy - something is royally screwed up */
+ assert((uread(BSP_UART_COM2, LSR) & THRE) != 0);
+
+ if(termios_stopped_com2)
+ {
+ /* CTS low */
+ termios_tx_hold_com2 = *buf;
+ termios_tx_hold_valid_com2 = 1;
+ return 0;
+ }
+
+ /* Write character */
+
+ uwrite(BSP_UART_COM2, THR, *buf & 0xff);
+
+ /* Enable interrupts if necessary */
+ if(!termios_tx_active_com2 && uart_data[BSP_UART_COM2].hwFlow)
+ {
+ termios_tx_active_com2 = 1;
+ uwrite(BSP_UART_COM2, IER,
+ (RECEIVE_ENABLE |
+ TRANSMIT_ENABLE |
+ RECEIVER_LINE_ST_ENABLE |
+ MODEM_ENABLE
+ )
+ );
+ }
+ else if(!termios_tx_active_com2)
+ {
+ termios_tx_active_com2 = 1;
+ uwrite(BSP_UART_COM2, IER,
+ (RECEIVE_ENABLE |
+ TRANSMIT_ENABLE |
+ RECEIVER_LINE_ST_ENABLE
+ )
+ );
+ }
+
+ return 0;
+}
+
+
+void
+BSP_uart_termios_isr_com1(void)
+{
+ unsigned char buf[40];
+ unsigned char val;
+ int off, ret, vect;
+
+ off = 0;
+
+ for(;;)
+ {
+ vect = uread(BSP_UART_COM1, IIR) & 0xf;
+
+ switch(vect)
+ {
+ case MODEM_STATUS :
+ val = uread(BSP_UART_COM1, MSR);
+ if(uart_data[BSP_UART_COM1].hwFlow)
+ {
+ if(val & CTS)
+ {
+ /* CTS high */
+ termios_stopped_com1 = 0;
+ if(termios_tx_hold_valid_com1)
+ {
+ termios_tx_hold_valid_com1 = 0;
+ BSP_uart_termios_write_com1(0, &termios_tx_hold_com1,
+ 1);
+ }
+ }
+ else
+ {
+ /* CTS low */
+ termios_stopped_com1 = 1;
+ }
+ }
+ break;
+ case NO_MORE_INTR :
+ /* No more interrupts */
+ if(off != 0)
+ {
+ /* Update rx buffer */
+ rtems_termios_enqueue_raw_characters(termios_ttyp_com1,
+ (char *)buf,
+ off);
+ }
+ return;
+ case TRANSMITTER_HODING_REGISTER_EMPTY :
+ /*
+ * TX holding empty: we have to disable these interrupts
+ * if there is nothing more to send.
+ */
+
+ ret = rtems_termios_dequeue_characters(termios_ttyp_com1, 1);
+
+ /* If nothing else to send disable interrupts */
+ if(ret == 0 && uart_data[BSP_UART_COM1].hwFlow)
+ {
+ uwrite(BSP_UART_COM1, IER,
+ (RECEIVE_ENABLE |
+ RECEIVER_LINE_ST_ENABLE |
+ MODEM_ENABLE
+ )
+ );
+ termios_tx_active_com1 = 0;
+ }
+ else if(ret == 0)
+ {
+ uwrite(BSP_UART_COM1, IER,
+ (RECEIVE_ENABLE |
+ RECEIVER_LINE_ST_ENABLE
+ )
+ );
+ termios_tx_active_com1 = 0;
+ }
+ break;
+ case RECEIVER_DATA_AVAIL :
+ case CHARACTER_TIMEOUT_INDICATION:
+ /* RX data ready */
+ assert(off < sizeof(buf));
+ buf[off++] = uread(BSP_UART_COM1, RBR);
+ break;
+ case RECEIVER_ERROR:
+ /* RX error: eat character */
+ uartError(BSP_UART_COM1);
+ break;
+ default:
+ /* Should not happen */
+ assert(0);
+ return;
+ }
+ }
+}
+
+void
+BSP_uart_termios_isr_com2()
+{
+ unsigned char buf[40];
+ unsigned char val;
+ int off, ret, vect;
+
+ off = 0;
+
+ for(;;)
+ {
+ vect = uread(BSP_UART_COM2, IIR) & 0xf;
+
+ switch(vect)
+ {
+ case MODEM_STATUS :
+ val = uread(BSP_UART_COM2, MSR);
+ if(uart_data[BSP_UART_COM2].hwFlow)
+ {
+ if(val & CTS)
+ {
+ /* CTS high */
+ termios_stopped_com2 = 0;
+ if(termios_tx_hold_valid_com2)
+ {
+ termios_tx_hold_valid_com2 = 0;
+ BSP_uart_termios_write_com2(0, &termios_tx_hold_com2,
+ 1);
+ }
+ }
+ else
+ {
+ /* CTS low */
+ termios_stopped_com2 = 1;
+ }
+ }
+ break;
+ case NO_MORE_INTR :
+ /* No more interrupts */
+ if(off != 0)
+ {
+ /* Update rx buffer */
+ rtems_termios_enqueue_raw_characters(termios_ttyp_com2,
+ (char *)buf,
+ off);
+ }
+ return;
+ case TRANSMITTER_HODING_REGISTER_EMPTY :
+ /*
+ * TX holding empty: we have to disable these interrupts
+ * if there is nothing more to send.
+ */
+
+ ret = rtems_termios_dequeue_characters(termios_ttyp_com2, 1);
+
+ /* If nothing else to send disable interrupts */
+ if(ret == 0 && uart_data[BSP_UART_COM2].hwFlow)
+ {
+ uwrite(BSP_UART_COM2, IER,
+ (RECEIVE_ENABLE |
+ RECEIVER_LINE_ST_ENABLE |
+ MODEM_ENABLE
+ )
+ );
+ termios_tx_active_com2 = 0;
+ }
+ else if(ret == 0)
+ {
+ uwrite(BSP_UART_COM2, IER,
+ (RECEIVE_ENABLE |
+ RECEIVER_LINE_ST_ENABLE
+ )
+ );
+ termios_tx_active_com2 = 0;
+ }
+ break;
+ case RECEIVER_DATA_AVAIL :
+ case CHARACTER_TIMEOUT_INDICATION:
+ /* RX data ready */
+ assert(off < sizeof(buf));
+ buf[off++] = uread(BSP_UART_COM2, RBR);
+ break;
+ case RECEIVER_ERROR:
+ /* RX error: eat character */
+ uartError(BSP_UART_COM2);
+ break;
+ default:
+ /* Should not happen */
+ assert(0);
+ return;
+ }
+ }
+}
+
+
+/* ================= GDB support ===================*/
+static int sav[4];
+
+/*
+ * Interrupt service routine for COM1 - all,
+ * it does it check whether ^C is received
+ * if yes it will flip TF bit before returning
+ * Note: it should be installed as raw interrupt
+ * handler
+ */
+
+asm (".p2align 4");
+asm (".text");
+asm (".globl BSP_uart_dbgisr_com1");
+asm ("BSP_uart_dbgisr_com1:");
+asm (" movl %eax, sav"); /* Save eax */
+asm (" movl %ebx, sav + 4"); /* Save ebx */
+asm (" movl %edx, sav + 8"); /* Save edx */
+
+asm (" movl $0, %ebx"); /* Clear flag */
+
+/*
+ * We know that only receive related interrupts
+ * are available, eat chars
+ */
+asm ("uart_dbgisr_com1_1:");
+asm (" movw $0x3FD, %dx");
+asm (" inb %dx, %al"); /* Read LSR */
+asm (" andb $1, %al");
+asm (" cmpb $0, %al");
+asm (" je uart_dbgisr_com1_2");
+asm (" movw $0x3F8, %dx");
+asm (" inb %dx, %al"); /* Get input character */
+asm (" cmpb $3, %al");
+asm (" jne uart_dbgisr_com1_1");
+
+/* ^C received, set flag */
+asm (" movl $1, %ebx");
+asm (" jmp uart_dbgisr_com1_1");
+
+/* All chars read */
+asm ("uart_dbgisr_com1_2:");
+
+/* If flag is set we have to tweak TF */
+asm (" cmpl $0, %ebx");
+asm (" je uart_dbgisr_com1_3");
+
+/* Flag is set */
+asm (" movl sav+4, %ebx"); /* Restore ebx */
+asm (" movl sav+8, %edx"); /* Restore edx */
+
+/* Set TF bit */
+asm (" popl %eax"); /* Pop eip */
+asm (" movl %eax, sav + 4"); /* Save it */
+asm (" popl %eax"); /* Pop cs */
+asm (" movl %eax, sav + 8"); /* Save it */
+asm (" popl %eax"); /* Pop flags */
+asm (" orl $0x100, %eax"); /* Modify it */
+asm (" pushl %eax"); /* Push it back */
+asm (" movl sav+8, %eax"); /* Put back cs */
+asm (" pushl %eax");
+asm (" movl sav+4, %eax"); /* Put back eip */
+asm (" pushl %eax");
+
+/* Acknowledge IRQ */
+asm (" movb $0x20, %al");
+asm (" outb %al, $0x20");
+asm (" movl sav, %eax"); /* Restore eax */
+asm (" iret"); /* Done */
+
+/* Flag is not set */
+asm("uart_dbgisr_com1_3:");
+asm (" movl sav+4, %ebx"); /* Restore ebx */
+asm (" movl sav+8, %edx"); /* Restore edx */
+
+/* Acknowledge irq */
+asm (" movb $0x20, %al");
+asm (" outb %al, $0x20");
+asm (" movl sav, %eax"); /* Restore eax */
+asm (" iret"); /* Done */
+
+
+/*
+ * Interrupt service routine for COM2 - all,
+ * it does it check whether ^C is received
+ * if yes it will flip TF bit before returning
+ * Note: it has to be installed as raw interrupt
+ * handler
+ */
+asm (".p2align 4");
+asm (".text");
+asm (".globl BSP_uart_dbgisr_com2");
+asm ("BSP_uart_dbgisr_com2:");
+asm (" movl %eax, sav"); /* Save eax */
+asm (" movl %ebx, sav + 4"); /* Save ebx */
+asm (" movl %edx, sav + 8"); /* Save edx */
+
+asm (" movl $0, %ebx"); /* Clear flag */
+
+/*
+ * We know that only receive related interrupts
+ * are available, eat chars
+ */
+asm ("uart_dbgisr_com2_1:");
+asm (" movw $0x2FD, %dx");
+asm (" inb %dx, %al"); /* Read LSR */
+asm (" andb $1, %al");
+asm (" cmpb $0, %al");
+asm (" je uart_dbgisr_com2_2");
+asm (" movw $0x2F8, %dx");
+asm (" inb %dx, %al"); /* Get input character */
+asm (" cmpb $3, %al");
+asm (" jne uart_dbgisr_com2_1");
+
+/* ^C received, set flag */
+asm (" movl $1, %ebx");
+asm (" jmp uart_dbgisr_com2_1");
+
+/* All chars read */
+asm ("uart_dbgisr_com2_2:");
+
+/* If flag is set we have to tweak TF */
+asm (" cmpl $0, %ebx");
+asm (" je uart_dbgisr_com2_3");
+
+/* Flag is set */
+asm (" movl sav+4, %ebx"); /* Restore ebx */
+asm (" movl sav+8, %edx"); /* Restore edx */
+
+/* Set TF bit */
+asm (" popl %eax"); /* Pop eip */
+asm (" movl %eax, sav + 4"); /* Save it */
+asm (" popl %eax"); /* Pop cs */
+asm (" movl %eax, sav + 8"); /* Save it */
+asm (" popl %eax"); /* Pop flags */
+asm (" orl $0x100, %eax"); /* Modify it */
+asm (" pushl %eax"); /* Push it back */
+asm (" movl sav+8, %eax"); /* Put back cs */
+asm (" pushl %eax");
+asm (" movl sav+4, %eax"); /* Put back eip */
+asm (" pushl %eax");
+
+/* Acknowledge IRQ */
+asm (" movb $0x20, %al");
+asm (" outb %al, $0x20");
+asm (" movl sav, %eax"); /* Restore eax */
+asm (" iret"); /* Done */
+
+/* Flag is not set */
+asm("uart_dbgisr_com2_3:");
+asm (" movl sav+4, %ebx"); /* Restore ebx */
+asm (" movl sav+8, %edx"); /* Restore edx */
+
+/* Acknowledge irq */
+asm (" movb $0x20, %al");
+asm (" outb %al, $0x20");
+asm (" movl sav, %eax"); /* Restore eax */
+asm (" iret"); /* Done */
+
+
+
+
+
+
diff --git a/c/src/lib/libbsp/i386/shared/comm/uart.h b/c/src/lib/libbsp/i386/shared/comm/uart.h
new file mode 100644
index 0000000000..e43ac9900c
--- /dev/null
+++ b/c/src/lib/libbsp/i386/shared/comm/uart.h
@@ -0,0 +1,169 @@
+
+
+/*
+ * This software is Copyright (C) 1998 by T.sqware - all rights limited
+ * It is provided in to the public domain "as is", can be freely modified
+ * as far as this copyight notice is kept unchanged, but does not imply
+ * an endorsement by T.sqware of the product in which it is included.
+ */
+
+#ifndef _BSPUART_H
+#define _BSPUART_H
+
+void BSP_uart_init(int uart, int baud, int hwFlow);
+void BSP_uart_set_baud(int aurt, int baud);
+void BSP_uart_intr_ctrl(int uart, int cmd);
+void BSP_uart_throttle(int uart);
+void BSP_uart_unthrottle(int uart);
+int BSP_uart_polled_status(int uart);
+void BSP_uart_polled_write(int uart, int val);
+int BSP_uart_polled_read(int uart);
+void BSP_uart_termios_set(int uart, void *ttyp);
+int BSP_uart_termios_write_com1(int minor, const char *buf, int len);
+int BSP_uart_termios_write_com2(int minor, const char *buf, int len);
+void BSP_uart_termios_isr_com1();
+void BSP_uart_termios_isr_com2();
+void BSP_uart_dbgisr_com1(void);
+void BSP_uart_dbgisr_com2(void);
+extern unsigned BSP_poll_char_via_serial(void);
+extern void BSP_output_char_via_serial(int val);
+extern int BSPConsolePort;
+extern int BSPBaseBaud;
+/*
+ * Command values for BSP_uart_intr_ctrl(),
+ * values are strange in order to catch errors
+ * with assert
+ */
+#define BSP_UART_INTR_CTRL_DISABLE (0)
+#define BSP_UART_INTR_CTRL_GDB (0xaa) /* RX only */
+#define BSP_UART_INTR_CTRL_ENABLE (0xbb) /* Normal operations */
+#define BSP_UART_INTR_CTRL_TERMIOS (0xcc) /* RX & line status */
+
+/* Return values for uart_polled_status() */
+#define BSP_UART_STATUS_ERROR (-1) /* No character */
+#define BSP_UART_STATUS_NOCHAR (0) /* No character */
+#define BSP_UART_STATUS_CHAR (1) /* Character present */
+#define BSP_UART_STATUS_BREAK (2) /* Break point is detected */
+
+/* PC UART definitions */
+#define BSP_UART_COM1 (0)
+#define BSP_UART_COM2 (1)
+
+/*
+ * Base IO for UART
+ */
+
+#define COM1_BASE_IO 0x3F8
+#define COM2_BASE_IO 0x2F8
+
+/*
+ * Offsets from base
+ */
+
+/* DLAB 0 */
+#define RBR (0) /* Rx Buffer Register (read) */
+#define THR (0) /* Tx Buffer Register (write) */
+#define IER (1) /* Interrupt Enable Register */
+
+/* DLAB X */
+#define IIR (2) /* Interrupt Ident Register (read) */
+#define FCR (2) /* FIFO Control Register (write) */
+#define LCR (3) /* Line Control Register */
+#define MCR (4) /* Modem Control Register */
+#define LSR (5) /* Line Status Register */
+#define MSR (6) /* Modem Status Register */
+#define SCR (7) /* Scratch register */
+
+/* DLAB 1 */
+#define DLL (0) /* Divisor Latch, LSB */
+#define DLM (1) /* Divisor Latch, MSB */
+#define AFR (2) /* Alternate Function register */
+
+/*
+ * Interrupt source definition via IIR
+ */
+#define MODEM_STATUS 0
+#define NO_MORE_INTR 1
+#define TRANSMITTER_HODING_REGISTER_EMPTY 2
+#define RECEIVER_DATA_AVAIL 4
+#define RECEIVER_ERROR 6
+#define CHARACTER_TIMEOUT_INDICATION 12
+
+/*
+ * Bits definition of IER
+ */
+#define RECEIVE_ENABLE 0x1
+#define TRANSMIT_ENABLE 0x2
+#define RECEIVER_LINE_ST_ENABLE 0x4
+#define MODEM_ENABLE 0x8
+#define INTERRUPT_DISABLE 0x0
+
+/*
+ * Bits definition of the Line Status Register (LSR)
+ */
+#define DR 0x01 /* Data Ready */
+#define OE 0x02 /* Overrun Error */
+#define PE 0x04 /* Parity Error */
+#define FE 0x08 /* Framing Error */
+#define BI 0x10 /* Break Interrupt */
+#define THRE 0x20 /* Transmitter Holding Register Empty */
+#define TEMT 0x40 /* Transmitter Empty */
+#define ERFIFO 0x80 /* Error receive Fifo */
+
+/*
+ * Bits definition of the MODEM Control Register (MCR)
+ */
+#define DTR 0x01 /* Data Terminal Ready */
+#define RTS 0x02 /* Request To Send */
+#define OUT_1 0x04 /* Output 1, (reserved on COMPAQ I/O Board) */
+#define OUT_2 0x08 /* Output 2, Enable Asynchronous Port Interrupts */
+#define LB 0x10 /* Enable Internal Loop Back */
+
+/*
+ * Bits definition of the Line Control Register (LCR)
+ */
+#define CHR_5_BITS 0
+#define CHR_6_BITS 1
+#define CHR_7_BITS 2
+#define CHR_8_BITS 3
+
+#define WL 0x03 /* Word length mask */
+#define STB 0x04 /* 1 Stop Bit, otherwise 2 Stop Bits */
+#define PEN 0x08 /* Parity Enabled */
+#define EPS 0x10 /* Even Parity Select, otherwise Odd */
+#define SP 0x20 /* Stick Parity */
+#define BCB 0x40 /* Break Control Bit */
+#define DLAB 0x80 /* Enable Divisor Latch Access */
+
+/*
+ * Bits definition of the MODEM Status Register (MSR)
+ */
+#define DCTS 0x01 /* Delta Clear To Send */
+#define DDSR 0x02 /* Delta Data Set Ready */
+#define TERI 0x04 /* Trailing Edge Ring Indicator */
+#define DDCD 0x08 /* Delta Carrier Detect Indicator */
+#define CTS 0x10 /* Clear To Send (when loop back is active) */
+#define DSR 0x20 /* Data Set Ready (when loop back is active) */
+#define RI 0x40 /* Ring Indicator (when loop back is active) */
+#define DCD 0x80 /* Data Carrier Detect (when loop back is active) */
+
+/*
+ * Bits definition of the FIFO Control Register : WD16C552 or NS16550
+ */
+
+#define FIFO_CTRL 0x01 /* Set to 1 permit access to other bits */
+#define FIFO_EN 0x01 /* Enable the FIFO */
+#define XMIT_RESET 0x02 /* Transmit FIFO Reset */
+#define RCV_RESET 0x04 /* Receive FIFO Reset */
+#define FCR3 0x08 /* do not understand manual! */
+
+#define RECEIVE_FIFO_TRIGGER1 0x0 /* trigger recieve interrupt after 1 byte */
+#define RECEIVE_FIFO_TRIGGER4 0x40 /* trigger recieve interrupt after 4 byte */
+#define RECEIVE_FIFO_TRIGGER8 0x80 /* trigger recieve interrupt after 8 byte */
+#define RECEIVE_FIFO_TRIGGER12 0xc0 /* trigger recieve interrupt after 12 byte */
+#define TRIG_LEVEL 0xc0 /* Mask for the trigger level */
+
+#endif /* _BSPUART_H */
+
+
+
diff --git a/c/src/lib/libbsp/i386/shared/irq/irq.c b/c/src/lib/libbsp/i386/shared/irq/irq.c
index 9dea372e0f..cd38ec51c4 100644
--- a/c/src/lib/libbsp/i386/shared/irq/irq.c
+++ b/c/src/lib/libbsp/i386/shared/irq/irq.c
@@ -21,19 +21,19 @@
* pointer to the mask representing the additionnal irq vectors
* that must be disabled when a particular entry is activated.
* They will be dynamically computed from teh prioruty table given
- * in pc386_rtems_irq_mngt_set();
+ * in BSP_rtems_irq_mngt_set();
* CAUTION : this table is accessed directly by interrupt routine
* prologue.
*/
-rtems_i8259_masks irq_mask_or_tbl[PC_386_IRQ_LINES_NUMBER];
+rtems_i8259_masks irq_mask_or_tbl[BSP_IRQ_LINES_NUMBER];
/*
- * Copy of data given via initial pc386_rtems_irq_mngt_set() for
+ * Copy of data given via initial BSP_rtems_irq_mngt_set() for
* the sake of efficiency.
* CAUTION : this table is accessed directly by interrupt routine
* prologue.
*/
-rtems_irq_hdl current_irq[PC_386_IRQ_LINES_NUMBER];
+rtems_irq_hdl current_irq[BSP_IRQ_LINES_NUMBER];
/*
* default handler connected on each irq after bsp initialization
*/
@@ -56,19 +56,19 @@ static rtems_irq_connect_data* rtems_hdl_tbl;
rtems_i8259_masks i8259s_cache;
/*-------------------------------------------------------------------------+
-| Function: PC386_irq_disable_at_i8259s
+| Function: BSP_irq_disable_at_i8259s
| Description: Mask IRQ line in appropriate PIC chip.
| Global Variables: i8259s_cache
| Arguments: vector_offset - number of IRQ line to mask.
| Returns: Nothing.
+--------------------------------------------------------------------------*/
-int pc386_irq_disable_at_i8259s (const rtems_irq_symbolic_name irqLine)
+int BSP_irq_disable_at_i8259s (const rtems_irq_symbolic_name irqLine)
{
unsigned short mask;
unsigned int level;
- if ( ((int)irqLine < PC_386_LOWEST_OFFSET) ||
- ((int)irqLine > PC_386_MAX_OFFSET )
+ if ( ((int)irqLine < BSP_LOWEST_OFFSET) ||
+ ((int)irqLine > BSP_MAX_OFFSET )
)
return 1;
@@ -91,19 +91,19 @@ int pc386_irq_disable_at_i8259s (const rtems_irq_symbolic_name irqLine)
}
/*-------------------------------------------------------------------------+
-| Function: pc386_irq_enable_at_i8259s
+| Function: BSP_irq_enable_at_i8259s
| Description: Unmask IRQ line in appropriate PIC chip.
| Global Variables: i8259s_cache
| Arguments: irqLine - number of IRQ line to mask.
| Returns: Nothing.
+--------------------------------------------------------------------------*/
-int pc386_irq_enable_at_i8259s (const rtems_irq_symbolic_name irqLine)
+int BSP_irq_enable_at_i8259s (const rtems_irq_symbolic_name irqLine)
{
unsigned short mask;
unsigned int level;
- if ( ((int)irqLine < PC_386_LOWEST_OFFSET) ||
- ((int)irqLine > PC_386_MAX_OFFSET )
+ if ( ((int)irqLine < BSP_LOWEST_OFFSET) ||
+ ((int)irqLine > BSP_MAX_OFFSET )
)
return 1;
@@ -125,12 +125,12 @@ int pc386_irq_enable_at_i8259s (const rtems_irq_symbolic_name irqLine)
return 0;
} /* mask_irq */
-int pc386_irq_enabled_at_i8259s (const rtems_irq_symbolic_name irqLine)
+int BSP_irq_enabled_at_i8259s (const rtems_irq_symbolic_name irqLine)
{
unsigned short mask;
- if ( ((int)irqLine < PC_386_LOWEST_OFFSET) ||
- ((int)irqLine > PC_386_MAX_OFFSET )
+ if ( ((int)irqLine < BSP_LOWEST_OFFSET) ||
+ ((int)irqLine > BSP_MAX_OFFSET )
)
return 1;
@@ -140,16 +140,16 @@ int pc386_irq_enabled_at_i8259s (const rtems_irq_symbolic_name irqLine)
/*-------------------------------------------------------------------------+
-| Function: pc386_irq_ack_at_i8259s
+| Function: BSP_irq_ack_at_i8259s
| Description: Signal generic End Of Interrupt (EOI) to appropriate PIC.
| Global Variables: None.
| Arguments: irqLine - number of IRQ line to acknowledge.
| Returns: Nothing.
+--------------------------------------------------------------------------*/
-int pc386_irq_ack_at_i8259s (const rtems_irq_symbolic_name irqLine)
+int BSP_irq_ack_at_i8259s (const rtems_irq_symbolic_name irqLine)
{
- if ( ((int)irqLine < PC_386_LOWEST_OFFSET) ||
- ((int)irqLine > PC_386_MAX_OFFSET )
+ if ( ((int)irqLine < BSP_LOWEST_OFFSET) ||
+ ((int)irqLine > BSP_MAX_OFFSET )
)
return 1;
@@ -212,7 +212,7 @@ static void make_copy_of_handlers ()
static int isValidInterrupt(int irq)
{
- if ( (irq < PC_386_LOWEST_OFFSET) || (irq > PC_386_MAX_OFFSET))
+ if ( (irq < BSP_LOWEST_OFFSET) || (irq > BSP_MAX_OFFSET))
return 0;
return 1;
}
@@ -221,7 +221,7 @@ static int isValidInterrupt(int irq)
* ------------------------ RTEMS Single Irq Handler Mngt Routines ----------------
*/
-int pc386_install_rtems_irq_handler (const rtems_irq_connect_data* irq)
+int BSP_install_rtems_irq_handler (const rtems_irq_connect_data* irq)
{
unsigned int level;
@@ -251,7 +251,7 @@ int pc386_install_rtems_irq_handler (const rtems_irq_connect_data* irq)
/*
* Enable interrupt at PIC level
*/
- pc386_irq_enable_at_i8259s (irq->name);
+ BSP_irq_enable_at_i8259s (irq->name);
/*
* Enable interrupt on device
*/
@@ -263,7 +263,7 @@ int pc386_install_rtems_irq_handler (const rtems_irq_connect_data* irq)
}
-int pc386_get_current_rtems_irq_handler (rtems_irq_connect_data* irq)
+int BSP_get_current_rtems_irq_handler (rtems_irq_connect_data* irq)
{
if (!isValidInterrupt(irq->name)) {
return 0;
@@ -272,7 +272,7 @@ int pc386_get_current_rtems_irq_handler (rtems_irq_connect_data* irq)
return 1;
}
-int pc386_remove_rtems_irq_handler (const rtems_irq_connect_data* irq)
+int BSP_remove_rtems_irq_handler (const rtems_irq_connect_data* irq)
{
unsigned int level;
@@ -294,7 +294,7 @@ int pc386_remove_rtems_irq_handler (const rtems_irq_connect_data* irq)
/*
* disable interrupt at PIC level
*/
- pc386_irq_disable_at_i8259s (irq->name);
+ BSP_irq_disable_at_i8259s (irq->name);
/*
* Disable interrupt on device
@@ -317,7 +317,7 @@ int pc386_remove_rtems_irq_handler (const rtems_irq_connect_data* irq)
* ------------------------ RTEMS Global Irq Handler Mngt Routines ----------------
*/
-int pc386_rtems_irq_mngt_set(rtems_irq_global_settings* config)
+int BSP_rtems_irq_mngt_set(rtems_irq_global_settings* config)
{
int i;
unsigned int level;
@@ -337,23 +337,23 @@ int pc386_rtems_irq_mngt_set(rtems_irq_global_settings* config)
for (i=0; i < internal_config->irqNb; i++) {
if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) {
- pc386_irq_enable_at_i8259s (i);
+ BSP_irq_enable_at_i8259s (i);
rtems_hdl_tbl[i].on(&rtems_hdl_tbl[i]);
}
else {
rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]);
- pc386_irq_disable_at_i8259s (i);
+ BSP_irq_disable_at_i8259s (i);
}
}
/*
* must disable slave pic anyway
*/
- pc386_irq_enable_at_i8259s (2);
+ BSP_irq_enable_at_i8259s (2);
_CPU_ISR_Enable(level);
return 1;
}
-int pc386_rtems_irq_mngt_get(rtems_irq_global_settings** config)
+int BSP_rtems_irq_mngt_get(rtems_irq_global_settings** config)
{
*config = internal_config;
return 0;
diff --git a/c/src/lib/libbsp/i386/shared/irq/irq.h b/c/src/lib/libbsp/i386/shared/irq/irq.h
index 5d628af83b..8bb6ce6f85 100644
--- a/c/src/lib/libbsp/i386/shared/irq/irq.h
+++ b/c/src/lib/libbsp/i386/shared/irq/irq.h
@@ -37,27 +37,27 @@ extern "C" {
typedef enum {
/* Base vector for our IRQ handlers. */
- PC386_IRQ_VECTOR_BASE = PC386_ASM_IRQ_VECTOR_BASE,
- PC_386_IRQ_LINES_NUMBER = 16,
- PC_386_LOWEST_OFFSET = 0,
- PC_386_MAX_OFFSET = PC_386_IRQ_LINES_NUMBER - 1,
+ BSP_IRQ_VECTOR_BASE = BSP_ASM_IRQ_VECTOR_BASE,
+ BSP_IRQ_LINES_NUMBER = 16,
+ BSP_LOWEST_OFFSET = 0,
+ BSP_MAX_OFFSET = BSP_IRQ_LINES_NUMBER - 1,
/*
- * Interrupt offset in comparison to PC386_ASM_IRQ_VECTOR_BASE
- * NB : 1) Interrupt vector number in IDT = offset + PC386_ASM_IRQ_VECTOR_BASE
+ * Interrupt offset in comparison to BSP_ASM_IRQ_VECTOR_BASE
+ * NB : 1) Interrupt vector number in IDT = offset + BSP_ASM_IRQ_VECTOR_BASE
* 2) The same name should be defined on all architecture
* so that handler connexion can be unchanged.
*/
- PC_386_PERIODIC_TIMER = 0,
+ BSP_PERIODIC_TIMER = 0,
- PC_386_KEYBOARD = 1,
+ BSP_KEYBOARD = 1,
- PC386_UART_COM2_IRQ = 3,
+ BSP_UART_COM2_IRQ = 3,
- PC386_UART_COM1_IRQ = 4,
+ BSP_UART_COM1_IRQ = 4,
- PC_386_RT_TIMER1 = 8,
+ BSP_RT_TIMER1 = 8,
- PC_386_RT_TIMER3 = 10
+ BSP_RT_TIMER3 = 10
}rtems_irq_symbolic_name;
@@ -127,7 +127,7 @@ typedef struct {
*/
rtems_irq_connect_data* irqHdlTbl;
/*
- * actual value of PC386_IRQ_VECTOR_BASE...
+ * actual value of BSP_IRQ_VECTOR_BASE...
*/
rtems_irq_symbolic_name irqBase;
/*
@@ -155,13 +155,13 @@ typedef struct {
* this function, even if the device asserts the interrupt line it will
* not be propagated further to the processor
*/
-int pc386_irq_disable_at_i8259s (const rtems_irq_symbolic_name irqLine);
+int BSP_irq_disable_at_i8259s (const rtems_irq_symbolic_name irqLine);
/*
* function to enable a particular irq at 8259 level. After calling
* this function, if the device asserts the interrupt line it will
* be propagated further to the processor
*/
-int pc386_irq_enable_at_i8259s (const rtems_irq_symbolic_name irqLine);
+int BSP_irq_enable_at_i8259s (const rtems_irq_symbolic_name irqLine);
/*
* function to acknoledge a particular irq at 8259 level. After calling
* this function, if a device asserts an enabled interrupt line it will
@@ -169,11 +169,11 @@ int pc386_irq_enable_at_i8259s (const rtems_irq_symbolic_name irqLine);
* writting raw handlers as this is automagically done for rtems managed
* handlers.
*/
-int pc386_irq_ack_at_i8259s (const rtems_irq_symbolic_name irqLine);
+int BSP_irq_ack_at_i8259s (const rtems_irq_symbolic_name irqLine);
/*
* function to check if a particular irq is enabled at 8259 level. After calling
*/
-int pc386_irq_enabled_at_i8259s (const rtems_irq_symbolic_name irqLine);
+int BSP_irq_enabled_at_i8259s (const rtems_irq_symbolic_name irqLine);
/*
* ------------------------ RTEMS Single Irq Handler Mngt Routines ----------------
*/
@@ -211,18 +211,18 @@ int pc386_irq_enabled_at_i8259s (const rtems_irq_symbolic_name irqLine);
* 6) restore initial execution flow
*
*/
-int pc386_install_rtems_irq_handler (const rtems_irq_connect_data*);
+int BSP_install_rtems_irq_handler (const rtems_irq_connect_data*);
/*
* function to get the current RTEMS irq handler for ptr->name. It enables to
* define hanlder chain...
*/
-int pc386_get_current_rtems_irq_handler (rtems_irq_connect_data* ptr);
+int BSP_get_current_rtems_irq_handler (rtems_irq_connect_data* ptr);
/*
* function to get disconnect the RTEMS irq handler for ptr->name.
* This function checks that the value given is the current one for safety reason.
* The user can use the previous function to get it.
*/
-int pc386_remove_rtems_irq_handler (const rtems_irq_connect_data*);
+int BSP_remove_rtems_irq_handler (const rtems_irq_connect_data*);
/*
* ------------------------ RTEMS Global Irq Handler Mngt Routines ----------------
@@ -233,10 +233,10 @@ int pc386_remove_rtems_irq_handler (const rtems_irq_connect_data*);
* The result of calling this function will be the same as if each individual
* handler (config->irqHdlTbl[i].hdl) different from "config->defaultEntry.hdl"
* has been individualy connected via
- * pc386_install_rtems_irq_handler(&config->irqHdlTbl[i])
+ * BSP_install_rtems_irq_handler(&config->irqHdlTbl[i])
* And each handler currently equal to config->defaultEntry.hdl
* has been previously disconnected via
- * pc386_remove_rtems_irq_handler (&config->irqHdlTbl[i])
+ * BSP_remove_rtems_irq_handler (&config->irqHdlTbl[i])
*
* This is to say that all information given will be used and not just
* only the space.
@@ -247,11 +247,11 @@ int pc386_remove_rtems_irq_handler (const rtems_irq_connect_data*);
* not be modified or declared on a stack.
*/
-int pc386_rtems_irq_mngt_set(rtems_irq_global_settings* config);
+int BSP_rtems_irq_mngt_set(rtems_irq_global_settings* config);
/*
* (Re) get info on current RTEMS interrupt management.
*/
-int pc386_rtems_irq_mngt_get(rtems_irq_global_settings**);
+int BSP_rtems_irq_mngt_get(rtems_irq_global_settings**);
#ifdef __cplusplus
}
diff --git a/c/src/lib/libbsp/i386/shared/irq/irq_asm.h b/c/src/lib/libbsp/i386/shared/irq/irq_asm.h
index bf6bb17e8e..af1289fb8f 100644
--- a/c/src/lib/libbsp/i386/shared/irq/irq_asm.h
+++ b/c/src/lib/libbsp/i386/shared/irq/irq_asm.h
@@ -15,7 +15,7 @@
#ifndef __IRQ_ASM_H__
#define __IRQ_ASM_H__
-#define PC386_ASM_IRQ_VECTOR_BASE 0x20
+#define BSP_ASM_IRQ_VECTOR_BASE 0x20
/* PIC's command and mask registers */
#define PIC_MASTER_COMMAND_IO_PORT 0x20 /* Master PIC command register */
#define PIC_SLAVE_COMMAND_IO_PORT 0xa0 /* Slave PIC command register */
diff --git a/c/src/lib/libbsp/i386/shared/irq/irq_init.c b/c/src/lib/libbsp/i386/shared/irq/irq_init.c
index ee6967d8d9..73cdf2e8c1 100644
--- a/c/src/lib/libbsp/i386/shared/irq/irq_init.c
+++ b/c/src/lib/libbsp/i386/shared/irq/irq_init.c
@@ -55,9 +55,9 @@ static rtems_raw_irq_connect_data idtHdl[IDT_SIZE];
/*
* Table used to store rtems managed interrupt handlers.
* Borrow the table to store raw handler entries at the beginning.
- * The table will be reinitialized before the call to pc386_rtems_irq_mngt_set().
+ * The table will be reinitialized before the call to BSP_rtems_irq_mngt_set().
*/
-static rtems_irq_connect_data rtemsIrq[PC_386_IRQ_LINES_NUMBER] = {
+static rtems_irq_connect_data rtemsIrq[BSP_IRQ_LINES_NUMBER] = {
{0,(rtems_irq_hdl)rtems_irq_prologue_0},
{0,(rtems_irq_hdl)rtems_irq_prologue_1},
{0,(rtems_irq_hdl)rtems_irq_prologue_2},
@@ -86,7 +86,7 @@ static rtems_irq_connect_data defaultIrq = {
0, nop_func , nop_func , nop_func , not_connected
};
-static rtems_irq_prio irqPrioTable[PC_386_IRQ_LINES_NUMBER]={
+static rtems_irq_prio irqPrioTable[BSP_IRQ_LINES_NUMBER]={
/*
* actual rpiorities for interrupt :
* 0 means that only current interrupt is masked
@@ -155,9 +155,9 @@ void rtems_irq_mngt_init()
* Patch the entry that will be used by RTEMS for interrupt management
* with RTEMS prologue.
*/
- for (i = 0; i < PC_386_IRQ_LINES_NUMBER; i++) {
+ for (i = 0; i < BSP_IRQ_LINES_NUMBER; i++) {
create_interrupt_gate_descriptor(&idtEntry,(rtems_raw_irq_hdl) rtemsIrq[i].hdl);
- idt_entry_tbl[i + PC386_ASM_IRQ_VECTOR_BASE] = idtEntry;
+ idt_entry_tbl[i + BSP_ASM_IRQ_VECTOR_BASE] = idtEntry;
}
/*
* At this point we have completed the initialization of IDT
@@ -167,20 +167,20 @@ void rtems_irq_mngt_init()
/*
* re-init the rtemsIrq table
*/
- for (i = 0; i < PC_386_IRQ_LINES_NUMBER; i++) {
+ for (i = 0; i < BSP_IRQ_LINES_NUMBER; i++) {
rtemsIrq[i] = defaultIrq;
rtemsIrq[i].name = i;
}
/*
* Init initial Interrupt management config
*/
- initial_config.irqNb = PC_386_IRQ_LINES_NUMBER;
+ initial_config.irqNb = BSP_IRQ_LINES_NUMBER;
initial_config.defaultEntry = defaultIrq;
initial_config.irqHdlTbl = rtemsIrq;
- initial_config.irqBase = PC386_ASM_IRQ_VECTOR_BASE;
+ initial_config.irqBase = BSP_ASM_IRQ_VECTOR_BASE;
initial_config.irqPrioTbl = irqPrioTable;
- if (!pc386_rtems_irq_mngt_set(&initial_config)) {
+ if (!BSP_rtems_irq_mngt_set(&initial_config)) {
/*
* put something here that will show the failure...
*/
@@ -200,7 +200,7 @@ void rtems_irq_mngt_init()
printk("idt_entry_tbl = %x Interrupt_descriptor_table addr = %x\n",
idt_entry_tbl, &Interrupt_descriptor_table);
- tmp = (unsigned) get_hdl_from_vector (PC386_ASM_IRQ_VECTOR_BASE + PC_386_PERIODIC_TIMER);
+ tmp = (unsigned) get_hdl_from_vector (BSP_ASM_IRQ_VECTOR_BASE + BSP_PERIODIC_TIMER);
printk("clock isr address from idt = %x should be %x\n",
tmp, (unsigned) rtems_irq_prologue_0);
}
diff --git a/c/src/lib/libbsp/i386/shared/pci/Makefile.in b/c/src/lib/libbsp/i386/shared/pci/Makefile.in
new file mode 100644
index 0000000000..607f26030a
--- /dev/null
+++ b/c/src/lib/libbsp/i386/shared/pci/Makefile.in
@@ -0,0 +1,32 @@
+#
+# $Id$
+#
+
+@SET_MAKE@
+srcdir = @srcdir@
+VPATH = @srcdir@
+RTEMS_ROOT = @top_srcdir@
+PROJECT_ROOT = @PROJECT_ROOT@
+
+H_FILES = $(srcdir)/pcibios.h
+
+#
+# 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 +=
+
+preinstall all: $(SRCS)
+ $(INSTALL) -m 444 $(SRCS) $(PROJECT_INCLUDE)
diff --git a/c/src/lib/libbsp/i386/shared/pci/pcibios.c b/c/src/lib/libbsp/i386/shared/pci/pcibios.c
new file mode 100644
index 0000000000..483e5df2a9
--- /dev/null
+++ b/c/src/lib/libbsp/i386/shared/pci/pcibios.c
@@ -0,0 +1,499 @@
+/*
+ * This software is Copyright (C) 1998 by T.sqware - all rights limited
+ * It is provided in to the public domain "as is", can be freely modified
+ * as far as this copyight notice is kept unchanged, but does not imply
+ * an endorsement by T.sqware of the product in which it is included.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+#include <assert.h>
+#include <pcibios.h>
+
+/*
+ * This is simpliest possible PCI BIOS, it assumes that addressing
+ * is flat and that stack is big enough
+ */
+
+
+static int pcibInitialized = 0;
+static unsigned int pcibEntry;
+
+/*
+ * Array to pass data between c and asm parts, at the time of
+ * writing I am not yet that familiar with extended asm feature
+ * of gcc. This code is not on performance path, so we can care
+ * relatively little about performance here
+ */
+static volatile unsigned int pcibExchg[5];
+
+static int pcib_convert_err(int err);
+
+/*
+ * Detects presense of PCI BIOS, returns
+ * error code
+ */
+int
+pcib_init(void)
+{
+ unsigned char *ucp;
+ unsigned char sum;
+ int i;
+
+ pcibInitialized = 0;
+
+ /* First, we have to look for BIOS-32 */
+ for(ucp=(unsigned char *)0xE0000; ucp < (unsigned char *)0xFFFFF; ucp+=0x10)
+ {
+ if(memcmp(ucp, "_32_", 4) != 0)
+ {
+ continue;
+ }
+
+ /* Got signature, check length */
+ if(*(ucp + 9) != 1)
+ {
+ continue;
+ }
+
+ /* Verify checksum */
+ sum = 0;
+ for(i=0; i<16; i++)
+ {
+ sum += *(ucp+i);
+ }
+
+ if(sum == 0)
+ {
+ /* found */
+ break;
+ }
+ }
+
+ if(ucp >= (unsigned char *)0xFFFFF)
+ {
+ /* BIOS-32 not found */
+ assert(0);
+ return PCIB_ERR_NOTPRESENT;
+ }
+
+ /* BIOS-32 found, let us find PCI BIOS */
+ ucp += 4;
+
+ pcibExchg[0] = *(unsigned int *)ucp;
+
+ asm (" pusha"); /* Push all registers */
+ asm (" movl pcibExchg, %edi"); /* Move entry point to esi */
+ asm (" movl $0x49435024, %eax"); /* Move signature to eax */
+ asm (" xorl %ebx, %ebx"); /* Zero ebx */
+ asm (" pushl %cs");
+ asm (" call *%edi"); /* Call entry */
+ asm (" movl %eax, pcibExchg");
+ asm (" movl %ebx, pcibExchg+4");
+ asm (" movl %ecx, pcibExchg+8");
+ asm (" movl %edx, pcibExchg+12");
+ asm (" popa");
+
+ if((pcibExchg[0] & 0xff) != 0)
+ {
+ /* Not found */
+ assert(0);
+ return PCIB_ERR_NOTPRESENT;
+ }
+
+ /* Found PCI entry point */
+ pcibEntry = pcibExchg[1] + pcibExchg[3];
+
+ /* Let us check whether PCI bios is present */
+ pcibExchg[0] = pcibEntry;
+
+ asm(" pusha");
+ asm(" movl pcibExchg, %edi");
+ asm(" movb $0xb1, %ah");
+ asm(" movb $0x01, %al");
+ asm (" pushl %cs");
+ asm(" call *%edi");
+ asm(" movl %eax, pcibExchg");
+ asm(" movl %ebx, pcibExchg+4");
+ asm(" movl %ecx, pcibExchg+8");
+ asm(" movl %edx, pcibExchg+12");
+ asm(" popa");
+
+ if((pcibExchg[0] & 0xff00) != 0)
+ {
+ /* Not found */
+ assert(0);
+ return PCIB_ERR_NOTPRESENT;
+ }
+
+ if(pcibExchg[3] != 0x20494350)
+ {
+ /* Signature does not match */
+ assert(0);
+ return PCIB_ERR_NOTPRESENT;
+ }
+
+ /* Success */
+
+ pcibInitialized = 1;
+ return PCIB_ERR_SUCCESS;
+}
+
+/*
+ * Find specified device and return its signature: combination
+ * of bus number, device number and function number
+ */
+int
+pcib_find_by_devid(int vendorId, int devId, int idx, int *sig)
+{
+ if(!pcibInitialized)
+ {
+ assert(0);
+ return PCIB_ERR_UNINITIALIZED;
+ }
+
+ pcibExchg[0] = pcibEntry;
+ pcibExchg[1] = vendorId;
+ pcibExchg[2] = devId;
+ pcibExchg[3] = idx;
+
+ asm(" pusha");
+ asm(" movl pcibExchg, %edi");
+ asm(" movb $0xb1, %ah");
+ asm(" movb $0x02, %al");
+ asm(" movl pcibExchg+4, %edx");
+ asm(" movl pcibExchg+8, %ecx");
+ asm(" movl pcibExchg+12, %esi");
+ asm(" pushl %cs");
+ asm(" call *%edi");
+ asm(" movl %eax, pcibExchg");
+ asm(" movl %ebx, pcibExchg+4");
+ asm(" popa");
+
+ *sig = pcibExchg[1] & 0xffff;
+
+ return pcib_convert_err((pcibExchg[0] >> 8) & 0xff);
+}
+
+/*
+ * Find specified class code return device signature: combination
+ * of bus number, device number and function number
+ */
+int
+pcib_find_by_class(int classCode, int idx, int *sig)
+{
+ if(!pcibInitialized)
+ {
+ assert(0);
+ return PCIB_ERR_UNINITIALIZED;
+ }
+
+ pcibExchg[0] = pcibEntry;
+ pcibExchg[1] = classCode;
+ pcibExchg[2] = idx;
+
+ asm(" pusha");
+ asm(" movl pcibExchg, %edi");
+ asm(" movb $0xb1, %ah");
+ asm(" movb $0x03, %al");
+ asm(" movl pcibExchg+4, %ecx");
+ asm(" movl pcibExchg+8, %esi");
+ asm(" pushl %cs");
+ asm(" call *%edi");
+ asm(" movl %eax, pcibExchg");
+ asm(" movl %ebx, pcibExchg+4");
+ asm(" popa");
+
+ if((pcibExchg[0] & 0xff00) != 0)
+ {
+ return pcib_convert_err((pcibExchg[0] >> 8) & 0xff);
+ }
+
+ *sig = pcibExchg[1] & 0xffff;
+
+ return PCIB_ERR_SUCCESS;
+}
+
+
+
+/*
+ * Generate Special Cycle
+ */
+int
+pcib_special_cycle(int busNo, int data)
+{
+ if(!pcibInitialized)
+ {
+ assert(0);
+ return PCIB_ERR_UNINITIALIZED;
+ }
+
+ pcibExchg[0] = pcibEntry;
+ pcibExchg[1] = busNo << 8;
+ pcibExchg[2] = data;
+
+ asm(" pusha");
+ asm(" movl pcibExchg, %edi");
+ asm(" movb $0xb1, %ah");
+ asm(" movb $0x06, %al");
+ asm(" movl pcibExchg+4, %ebx");
+ asm(" movl pcibExchg+8, %edx");
+ asm(" pushl %cs");
+ asm(" call *%edi");
+ asm(" movl %eax, pcibExchg");
+ asm(" movl %ebx, pcibExchg+4");
+ asm(" popa");
+
+ return pcib_convert_err((pcibExchg[0] >> 8) & 0xff);
+}
+
+
+/*
+ * Read byte from config space
+ */
+int
+pcib_conf_read8(int sig, int off, unsigned char *data)
+{
+ if(!pcibInitialized)
+ {
+ assert(0);
+ return PCIB_ERR_UNINITIALIZED;
+ }
+
+ pcibExchg[0] = pcibEntry;
+ pcibExchg[1] = sig;
+ pcibExchg[2] = off;
+
+ asm(" pusha");
+ asm(" movl pcibExchg, %esi");
+ asm(" movb $0xb1, %ah");
+ asm(" movb $0x08, %al");
+ asm(" movl pcibExchg+4, %ebx");
+ asm(" movl pcibExchg+8, %edi");
+ asm(" pushl %cs");
+ asm(" call *%esi");
+ asm(" movl %eax, pcibExchg");
+ asm(" movl %ecx, pcibExchg+4");
+ asm(" popa");
+
+ if((pcibExchg[0] & 0xff00) != 0)
+ {
+ return pcib_convert_err((pcibExchg[0] >> 8) & 0xff);
+ }
+
+ *data = (unsigned char)pcibExchg[1] & 0xff;
+
+ return PCIB_ERR_SUCCESS;
+}
+
+
+/*
+ * Read word from config space
+ */
+int
+pcib_conf_read16(int sig, int off, unsigned short *data)
+{
+ if(!pcibInitialized)
+ {
+ assert(0);
+ return PCIB_ERR_UNINITIALIZED;
+ }
+
+ pcibExchg[0] = pcibEntry;
+ pcibExchg[1] = sig;
+ pcibExchg[2] = off;
+
+ asm(" pusha");
+ asm(" movl pcibExchg, %esi");
+ asm(" movb $0xb1, %ah");
+ asm(" movb $0x09, %al");
+ asm(" movl pcibExchg+4, %ebx");
+ asm(" movl pcibExchg+8, %edi");
+ asm(" pushl %cs");
+ asm(" call *%esi");
+ asm(" movl %eax, pcibExchg");
+ asm(" movl %ecx, pcibExchg+4");
+ asm(" popa");
+
+ if((pcibExchg[0] & 0xff00) != 0)
+ {
+ return pcib_convert_err((pcibExchg[0] >> 8) & 0xff);
+ }
+
+ *data = (unsigned short)pcibExchg[1] & 0xffff;
+
+ return PCIB_ERR_SUCCESS;
+}
+
+
+/*
+ * Read dword from config space
+ */
+int
+pcib_conf_read32(int sig, int off, unsigned int *data)
+{
+ if(!pcibInitialized)
+ {
+ assert(0);
+ return PCIB_ERR_UNINITIALIZED;
+ }
+
+ pcibExchg[0] = pcibEntry;
+ pcibExchg[1] = sig;
+ pcibExchg[2] = off;
+
+ asm(" pusha");
+ asm(" movl pcibExchg, %esi");
+ asm(" movb $0xb1, %ah");
+ asm(" movb $0x0a, %al");
+ asm(" movl pcibExchg+4, %ebx");
+ asm(" movl pcibExchg+8, %edi");
+ asm(" pushl %cs");
+ asm(" call *%esi");
+ asm(" movl %eax, pcibExchg");
+ asm(" movl %ecx, pcibExchg+4");
+ asm(" popa");
+
+ if((pcibExchg[0] & 0xff00) != 0)
+ {
+ return pcib_convert_err((pcibExchg[0] >> 8) & 0xff);
+ }
+
+ *data = (unsigned int)pcibExchg[1];
+
+ return PCIB_ERR_SUCCESS;
+}
+
+
+/*
+ * Write byte into config space
+ */
+int
+pcib_conf_write8(int sig, int off, unsigned int data)
+{
+ if(!pcibInitialized)
+ {
+ assert(0);
+ return PCIB_ERR_UNINITIALIZED;
+ }
+
+ pcibExchg[0] = pcibEntry;
+ pcibExchg[1] = sig;
+ pcibExchg[2] = off;
+ pcibExchg[3] = data & 0xff;
+
+ asm(" pusha");
+ asm(" movl pcibExchg, %esi");
+ asm(" movb $0xb1, %ah");
+ asm(" movb $0x0b, %al");
+ asm(" movl pcibExchg+4, %ebx");
+ asm(" movl pcibExchg+8, %edi");
+ asm(" movl pcibExchg+12, %ecx");
+ asm(" pushl %cs");
+ asm(" call *%esi");
+ asm(" movl %eax, pcibExchg");
+ asm(" popa");
+
+ return pcib_convert_err((pcibExchg[0] >> 8) & 0xff);
+}
+
+/*
+ * Write word into config space
+ */
+int
+pcib_conf_write16(int sig, int off, unsigned int data)
+{
+ if(!pcibInitialized)
+ {
+ assert(0);
+ return PCIB_ERR_UNINITIALIZED;
+ }
+
+ pcibExchg[0] = pcibEntry;
+ pcibExchg[1] = sig;
+ pcibExchg[2] = off;
+ pcibExchg[3] = data & 0xffff;
+
+ asm(" pusha");
+ asm(" movl pcibExchg, %esi");
+ asm(" movb $0xb1, %ah");
+ asm(" movb $0x0c, %al");
+ asm(" movl pcibExchg+4, %ebx");
+ asm(" movl pcibExchg+8, %edi");
+ asm(" movl pcibExchg+12, %ecx");
+ asm(" pushl %cs");
+ asm(" call *%esi");
+ asm(" movl %eax, pcibExchg");
+ asm(" popa");
+
+ return pcib_convert_err((pcibExchg[0] >> 8) & 0xff);
+}
+
+
+
+/*
+ * Write dword into config space
+ */
+int
+pcib_conf_write32(int sig, int off, unsigned int data)
+{
+ if(!pcibInitialized)
+ {
+ assert(0);
+ return PCIB_ERR_UNINITIALIZED;
+ }
+
+ pcibExchg[0] = pcibEntry;
+ pcibExchg[1] = sig;
+ pcibExchg[2] = off;
+ pcibExchg[3] = data;
+
+ asm(" pusha");
+ asm(" movl pcibExchg, %esi");
+ asm(" movb $0xb1, %ah");
+ asm(" movb $0x0d, %al");
+ asm(" movl pcibExchg+4, %ebx");
+ asm(" movl pcibExchg+8, %edi");
+ asm(" movl pcibExchg+12, %ecx");
+ asm(" pushl %cs");
+ asm(" call *%esi");
+ asm(" movl %eax, pcibExchg");
+ asm(" popa");
+
+ return pcib_convert_err((pcibExchg[0] >> 8) & 0xff);
+}
+
+
+static int
+pcib_convert_err(int err)
+{
+ switch(err & 0xff)
+ {
+ case 0:
+ return PCIB_ERR_SUCCESS;
+ case 0x81:
+ return PCIB_ERR_NOFUNC;
+ case 0x83:
+ return PCIB_ERR_BADVENDOR;
+ case 0x86:
+ return PCIB_ERR_DEVNOTFOUND;
+ case 0x87:
+ return PCIB_ERR_BADREG;
+ default:
+ assert(0);
+ break;
+ }
+ return PCIB_ERR_NOFUNC;
+}
+
+
+
+
+
+
+
+
+
+
diff --git a/c/src/lib/libbsp/i386/shared/pci/pcibios.h b/c/src/lib/libbsp/i386/shared/pci/pcibios.h
new file mode 100644
index 0000000000..40bc3c861a
--- /dev/null
+++ b/c/src/lib/libbsp/i386/shared/pci/pcibios.h
@@ -0,0 +1,46 @@
+/*
+ * This software is Copyright (C) 1998 by T.sqware - all rights limited
+ * It is provided in to the public domain "as is", can be freely modified
+ * as far as this copyight notice is kept unchanged, but does not imply
+ * an endorsement by T.sqware of the product in which it is included.
+ */
+
+#ifndef _PCIB_H
+#define _PCIB_H
+
+/* Error codes */
+#define PCIB_ERR_SUCCESS (0)
+#define PCIB_ERR_UNINITIALIZED (-1) /* PCI BIOS is not initilized */
+#define PCIB_ERR_NOTPRESENT (-2) /* PCI BIOS not present */
+#define PCIB_ERR_NOFUNC (-3) /* Function not supported */
+#define PCIB_ERR_BADVENDOR (-4) /* Bad Vendor ID */
+#define PCIB_ERR_DEVNOTFOUND (-5) /* Device not found */
+#define PCIB_ERR_BADREG (-6) /* Bad register number */
+
+/*
+ * Make device signature from bus number, device numebr and function
+ * number
+ */
+#define PCIB_DEVSIG_MAKE(b,d,f) ((b<<8)|(d<<3)|(f))
+
+/*
+ * Extract valrous part from device signature
+ */
+#define PCIB_DEVSIG_BUS(x) (((x)>>8) &0xff)
+#define PCIB_DEVSIG_DEV(x) (((x)>>3) & 0x1f)
+#define PCIB_DEVSIG_FUNC(x) ((x) & 0x7)
+
+int pcib_init(void);
+int pcib_find_by_devid(int vendorId, int devId, int idx, int *sig);
+int pcib_find_by_class(int classCode, int idx, int *sig);
+int pcib_special_cycle(int busNo, int data);
+int pcib_conf_read8(int sig, int off, unsigned char *data);
+int pcib_conf_read16(int sig, int off, unsigned short *data);
+int pcib_conf_read32(int sig, int off, unsigned int *data);
+int pcib_conf_write8(int sig, int off, unsigned int data);
+int pcib_conf_write16(int sig, int off, unsigned int data);
+int pcib_conf_write32(int sig, int off, unsigned int data);
+
+
+#endif /* _PCIB_H */
+