summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/i386/pc386
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2016-04-08 18:39:38 +1000
committerChris Johns <chrisj@rtems.org>2016-05-11 11:45:01 +1000
commit014292a164b8bb5286b6c7dae7c37a469ef6f0cc (patch)
treec7343485ef520fc71f36e5cf8271e08a2c1de789 /c/src/lib/libbsp/i386/pc386
parentbsp/qoriq: Add portal clear functions (diff)
downloadrtems-014292a164b8bb5286b6c7dae7c37a469ef6f0cc.tar.bz2
i386/pc386: Add support for the gdb stub to use available console drivers.
Move the gdb stub from the i386 UART code to use the libchip drivers. Use any ports discovered during the probes. Add gdb control to the boot command line. Change the device naming to the full device path, not a partial path. For example /dev/com1.
Diffstat (limited to '')
-rw-r--r--c/src/lib/libbsp/i386/pc386/Makefile.am5
-rw-r--r--c/src/lib/libbsp/i386/pc386/README23
-rw-r--r--c/src/lib/libbsp/i386/pc386/configure.ac6
-rw-r--r--c/src/lib/libbsp/i386/pc386/console/conscfg.c88
-rw-r--r--c/src/lib/libbsp/i386/pc386/console/console_control.c39
-rw-r--r--c/src/lib/libbsp/i386/pc386/console/console_select.c106
-rw-r--r--c/src/lib/libbsp/i386/pc386/console/gdb_select.c169
-rw-r--r--c/src/lib/libbsp/i386/pc386/console/uart_bus_pci.c135
-rw-r--r--c/src/lib/libbsp/i386/pc386/include/bsp.h3
-rw-r--r--c/src/lib/libbsp/i386/pc386/include/bspimpl.h12
-rw-r--r--c/src/lib/libbsp/i386/pc386/startup/bspstart.c29
-rw-r--r--c/src/lib/libbsp/i386/pc386/startup/ldsegs.S2
12 files changed, 399 insertions, 218 deletions
diff --git a/c/src/lib/libbsp/i386/pc386/Makefile.am b/c/src/lib/libbsp/i386/pc386/Makefile.am
index d9af7dd5a7..22d4bf1e46 100644
--- a/c/src/lib/libbsp/i386/pc386/Makefile.am
+++ b/c/src/lib/libbsp/i386/pc386/Makefile.am
@@ -132,6 +132,7 @@ libbsp_a_SOURCES += console/printk_support.c
libbsp_a_SOURCES += console/exar17d15x.c
libbsp_a_SOURCES += console/rtd316.c
libbsp_a_SOURCES += console/uart_bus_pci.c
+libbsp_a_SOURCES += console/gdb_select.c
# gdb
libbsp_a_SOURCES += ../../i386/shared/comm/i386-stub.c
@@ -181,8 +182,8 @@ libbsp_a_SOURCES += ide/idecfg.c
endif
if HAS_SMP
-libbsp_a_SOURCES += ../../i386/shared/smp/getcpuid.c
-libbsp_a_SOURCES += ../../i386/shared/smp/smp-imps.c
+libbsp_a_SOURCES += ../../i386/shared/smp/getcpuid.c
+libbsp_a_SOURCES += ../../i386/shared/smp/smp-imps.c
project_lib_DATA += appstart.$(OBJEXT)
appcpustart.$(OBJEXT): start/start16.S
diff --git a/c/src/lib/libbsp/i386/pc386/README b/c/src/lib/libbsp/i386/pc386/README
index bfebf1951c..4ed8829719 100644
--- a/c/src/lib/libbsp/i386/pc386/README
+++ b/c/src/lib/libbsp/i386/pc386/README
@@ -7,7 +7,7 @@ a Pentium or above, the TSC register is used for timing calibration
purposes rather than relying entirely on the i8254.
Partial support is implemented for more modern PCs which do not have
-a complete complement of legacy peripherals.
+a complete complement of legacy peripherals.
Console/Printk Device Selection
===============================
@@ -19,9 +19,9 @@ in the following order of priority:
+ VGA and keyboard
+ COM1 through COM4aaa
-+ Any COM devices on the PCI bus
++ Any COM devices on the PCI bus including IO and memory mapped.
-Beyond the dynamic probing for device presence, a combination of
+Beyond the dynamic probing for device presence, a combination of
configure and boot time options are available. By default, all devices
are enabled. The configure time options are:
@@ -45,7 +45,7 @@ specify the console and kernel debug IO device. The --printk
is then interpreted to specify the debug kernel IO device.
For example,
---console=com1 --printk=vgacons
+--console=/dev/com1 --printk=/dev/vgacons
specifies that com1 is to be used for stdin, stdout, and stderr
while the VGA console is to be used for kernel debug IO.
@@ -55,8 +55,21 @@ the RTEMS device /dev/com1.
The device name may be followed by a baud rate. The following
example illustrates this:
---console=com1,19200 --printk=vgacons
+--console=/dev/com1,19200 --printk=/dev/vgacons
If the specified device is not present, then a suitable fallback
device is selected. The fallback order is based upon the probe
order listed earlier.
+
+PCI UART devices are /dev/pcicom1 etc as they are probed and found.
+
+GDB
+===
+
+GDB can be support using:
+
+ --gdb=/dev/com1,115200 : where the device and baudrate are selectable.
+ --gdb-break : halt at a break point in the BSP and wait for GDB.
+ --gdb-remote-debug : Output the GDB remote protocol data to printk
+
+The GDB stub details and in shared/comm/GDB.HOWTO.
diff --git a/c/src/lib/libbsp/i386/pc386/configure.ac b/c/src/lib/libbsp/i386/pc386/configure.ac
index 17b7d02e3b..d62a9b332e 100644
--- a/c/src/lib/libbsp/i386/pc386/configure.ac
+++ b/c/src/lib/libbsp/i386/pc386/configure.ac
@@ -142,6 +142,12 @@ RTEMS_BSPOPTS_HELP([BSP_HAS_SMP],
[Always defined when on a pc386 to enable the pc386 support for
determining the CPU core number in an SMP configuration.])
+RTEMS_BSPOPTS_SET([BSP_GDB_STUB],[*],[1])
+RTEMS_BSPOPTS_HELP([BSP_GDB_STUB],
+[Defined by default. Enables use of the GDB stub for debugging via a
+ serial port.])
+AM_CONDITIONAL(BSP_GDB_STUB, test "$BSP_GDB_STUB" = "1")
+
## if this is an i386, does gas have good code16 support?
RTEMS_I386_GAS_CODE16
AM_CONDITIONAL(RTEMS_GAS_CODE16,[test "$RTEMS_GAS_CODE16" = "yes"])
diff --git a/c/src/lib/libbsp/i386/pc386/console/conscfg.c b/c/src/lib/libbsp/i386/pc386/console/conscfg.c
index 5b7ebc5d4a..82d3cf9f98 100644
--- a/c/src/lib/libbsp/i386/pc386/console/conscfg.c
+++ b/c/src/lib/libbsp/i386/pc386/console/conscfg.c
@@ -16,13 +16,14 @@
*/
#include <bsp.h>
+#include <bsp/bspimpl.h>
#include <libchip/serial.h>
#include <libchip/ns16550.h>
#if BSP_ENABLE_VGA
#include "vgacons.h"
#endif
#include <bsp/irq.h>
-#include <rtems/pci.h>
+#include "../../../shared/console_private.h"
#if BSP_ENABLE_VGA
#define VGA_CONSOLE_FUNCTIONS &vgacons_fns
@@ -43,7 +44,7 @@
#define COM3_BASE_IO 0x2F8
#define COM4_BASE_IO 0x2E8
- #define CLOCK_RATE (115200 * 16)
+ #define CLOCK_RATE (115200 * 16)
static uint8_t com_get_register(uint32_t addr, uint8_t i)
{
@@ -57,21 +58,26 @@
{
outport_byte( (addr + i), val );
}
-
- extern bool pc386_com1_com4_enabled(int);
#endif
#if (BSP_IS_EDISON == 1 )
extern const console_fns edison_fns;
#endif
-console_tbl Console_Configuration_Ports[] = {
-#if (BSP_IS_EDISON == 1)
+/*
+ * Default to the PC VGA console if present and configured.
+ */
+console_tbl Console_Configuration_Ports[] = {
+#if BSP_ENABLE_VGA
+ /*
+ * If present the VGA console must always be minor 0.
+ * See console_control.
+ */
{
- "/dev/com1", /* sDeviceName */
- -1, /* deviceType */
- &edison_fns, /* pDeviceFns */
- NULL, /* deviceProbe */
+ "/dev/vgacons", /* sDeviceName */
+ VGA_CONSOLE, /* deviceType */
+ VGA_CONSOLE_FUNCTIONS, /* pDeviceFns */
+ vgacons_probe, /* deviceProbe */
NULL, /* pDeviceFlow */
16, /* ulMargin */
8, /* ulHysteresis */
@@ -83,16 +89,22 @@ console_tbl Console_Configuration_Ports[] = {
NULL, /* setRegister */
NULL,/* unused */ /* getData */
NULL,/* unused */ /* setData */
- 0X0, /* ulClock */
- 0x0 /* ulIntVector -- base for port */
+ 0x0, /* ulClock */
+ 0x0 /* ulIntVector -- base for port */
},
#endif
-#if BSP_ENABLE_VGA
+};
+
+unsigned long Console_Configuration_Count =
+ (sizeof(Console_Configuration_Ports)/sizeof(console_tbl));
+
+static console_tbl Legacy_Ports[] = {
+#if (BSP_IS_EDISON == 1)
{
- "/dev/vgacons", /* sDeviceName */
- VGA_CONSOLE, /* deviceType */
- VGA_CONSOLE_FUNCTIONS, /* pDeviceFns */
- vgacons_probe, /* deviceProbe */
+ "/dev/com1", /* sDeviceName */
+ -1, /* deviceType */
+ &edison_fns, /* pDeviceFns */
+ NULL, /* deviceProbe */
NULL, /* pDeviceFlow */
16, /* ulMargin */
8, /* ulHysteresis */
@@ -104,8 +116,8 @@ console_tbl Console_Configuration_Ports[] = {
NULL, /* setRegister */
NULL,/* unused */ /* getData */
NULL,/* unused */ /* setData */
- 0X0, /* ulClock */
- 0x0 /* ulIntVector -- base for port */
+ 0x0, /* ulClock */
+ 0x0 /* ulIntVector -- base for port */
},
#endif
#if BSP_ENABLE_COM1_COM4
@@ -113,7 +125,7 @@ console_tbl Console_Configuration_Ports[] = {
"/dev/com1", /* sDeviceName */
SERIAL_NS16550, /* deviceType */
COM_CONSOLE_FUNCTIONS, /* pDeviceFns */
- pc386_com1_com4_enabled, /* deviceProbe */
+ NULL, /* deviceProbe */
NULL, /* pDeviceFlow */
16, /* ulMargin */
8, /* ulHysteresis */
@@ -132,7 +144,7 @@ console_tbl Console_Configuration_Ports[] = {
"/dev/com2", /* sDeviceName */
SERIAL_NS16550, /* deviceType */
COM_CONSOLE_FUNCTIONS, /* pDeviceFns */
- pc386_com1_com4_enabled, /* deviceProbe */
+ NULL, /* deviceProbe */
NULL, /* pDeviceFlow */
16, /* ulMargin */
8, /* ulHysteresis */
@@ -147,12 +159,11 @@ console_tbl Console_Configuration_Ports[] = {
CLOCK_RATE, /* ulClock */
BSP_UART_COM2_IRQ /* ulIntVector -- base for port */
},
-
{
"/dev/com3", /* sDeviceName */
SERIAL_NS16550, /* deviceType */
COM_CONSOLE_FUNCTIONS, /* pDeviceFns */
- pc386_com1_com4_enabled, /* deviceProbe */
+ NULL, /* deviceProbe */
NULL, /* pDeviceFlow */
16, /* ulMargin */
8, /* ulHysteresis */
@@ -167,12 +178,11 @@ console_tbl Console_Configuration_Ports[] = {
CLOCK_RATE, /* ulClock */
BSP_UART_COM3_IRQ /* ulIntVector -- base for port */
},
-
{
"/dev/com4", /* sDeviceName */
SERIAL_NS16550, /* deviceType */
COM_CONSOLE_FUNCTIONS, /* pDeviceFns */
- pc386_com1_com4_enabled, /* deviceProbe */
+ NULL, /* deviceProbe */
NULL, /* pDeviceFlow */
16, /* ulMargin */
8, /* ulHysteresis */
@@ -188,12 +198,26 @@ console_tbl Console_Configuration_Ports[] = {
BSP_UART_COM4_IRQ /* ulIntVector -- base for port */
},
#endif
-
};
-/*
- * Define a variable that contains the number of statically configured
- * console devices.
- */
-unsigned long Console_Configuration_Count = \
- (sizeof(Console_Configuration_Ports)/sizeof(console_tbl));
+#define Legacy_Port_Count \
+ (sizeof(Legacy_Ports)/sizeof(console_tbl))
+
+void legacy_uart_probe(void)
+{
+#if BSP_ENABLE_COM1_COM4
+ const char *opt;
+ /*
+ * Check the command line to see if com1-com4 are disabled.
+ */
+ opt = bsp_cmdline_arg("--disable-com1-com4");
+ if ( opt ) {
+ printk( "COM1-COM4: disabled\n" );
+ } else {
+ if (Legacy_Port_Count) {
+ printk("Legacy UART Ports: COM1-COM4\n");
+ console_register_devices( Legacy_Ports, Legacy_Port_Count );
+ }
+ }
+#endif
+}
diff --git a/c/src/lib/libbsp/i386/pc386/console/console_control.c b/c/src/lib/libbsp/i386/pc386/console/console_control.c
index a0b9220bba..3a454d97e9 100644
--- a/c/src/lib/libbsp/i386/pc386/console/console_control.c
+++ b/c/src/lib/libbsp/i386/pc386/console/console_control.c
@@ -1,5 +1,5 @@
/*
- * This file is an extension of the generic console driver
+ * This file is an extension of the generic console driver
* shell used by all console drivers using libchip, it contains
* the console_control routine, This bsp needs its own version
* of this method to handle the keyboard and mouse as a single
@@ -44,27 +44,28 @@ rtems_device_driver console_control(
)
{
#if BSP_ENABLE_VGA
- rtems_libio_ioctl_args_t *args = arg;
+ if (minor == 0) {
+ rtems_libio_ioctl_args_t *args = arg;
- switch (args->command) {
- default:
- if( vt_ioctl( args->command, (unsigned long)args->buffer ) != 0 )
- return rtems_termios_ioctl (arg);
- break;
+ switch (args->command) {
+ default:
+ if( vt_ioctl( args->command, (unsigned long)args->buffer ) != 0 )
+ return rtems_termios_ioctl (arg);
+ break;
- case MW_UID_REGISTER_DEVICE:
- printk( "SerialMouse: reg=%s\n", args->buffer );
- register_kbd_msg_queue( args->buffer, 0 );
- break;
+ case MW_UID_REGISTER_DEVICE:
+ printk( "SerialMouse: reg=%s\n", args->buffer );
+ register_kbd_msg_queue( args->buffer, 0 );
+ break;
- case MW_UID_UNREGISTER_DEVICE:
- unregister_kbd_msg_queue( 0 );
- break;
+ case MW_UID_UNREGISTER_DEVICE:
+ unregister_kbd_msg_queue( 0 );
+ break;
+ }
+
+ args->ioctl_return = 0;
+ return RTEMS_SUCCESSFUL;
}
-
- args->ioctl_return = 0;
- return RTEMS_SUCCESSFUL;
-#else
- return rtems_termios_ioctl (arg);
#endif
+ return rtems_termios_ioctl (arg);
}
diff --git a/c/src/lib/libbsp/i386/pc386/console/console_select.c b/c/src/lib/libbsp/i386/pc386/console/console_select.c
index 6a91a96083..f7e6bbc8e9 100644
--- a/c/src/lib/libbsp/i386/pc386/console/console_select.c
+++ b/c/src/lib/libbsp/i386/pc386/console/console_select.c
@@ -3,7 +3,7 @@
*
* @ingroup Console
*
- * @brief pc397 console select
+ * @brief pc386 console select
*
* This file contains a routine to select the console based upon a number
* of criteria.
@@ -33,24 +33,6 @@
#include <crt.h>
#endif
-#include <bsp/bspimpl.h>
-
-/*
- * Forward prototype
- */
-extern bool pc386_com1_com4_enabled(int);
-
-/*
- * This method is used to determine if COM1-COM4 are enabled based upon
- * boot command line arguments.
- */
-static bool are_com1_com4_enabled;
-
-bool pc386_com1_com4_enabled(int minor)
-{
- return are_com1_com4_enabled;
-}
-
/*
* Method to return true if the device associated with the
* minor number probs available.
@@ -97,48 +79,6 @@ static rtems_device_minor_number bsp_First_Available_Device( void )
rtems_fatal_error_occurred(RTEMS_IO_ERROR);
}
-static bool bsp_find_console_entry(
- const char *match,
- size_t length,
- rtems_device_minor_number *match_minor
-)
-{
- rtems_device_minor_number minor;
- const char *name;
-
- for (minor=0; minor < Console_Port_Count ; minor++) {
- console_tbl *cptr = Console_Port_Tbl[minor];
-
- /*
- * Console table entries include /dev/ prefix, device names passed
- * in on command line do not.
- */
- name = cptr->sDeviceName + sizeof("/dev");
- if ( !strncmp( name, match, length ) ) {
- *match_minor = minor;
- return true;
- }
- }
-
- return false;
-}
-
-static void parse_com1_com4_enable(void)
-{
- static const char *opt;
-
- /*
- * Check the command line to see if com1-com4 are disabled.
- */
- opt = bsp_cmdline_arg("--disable-com1-com4");
- if ( opt ) {
- printk( "Disable COM1-COM4 per boot argument\n" );
- are_com1_com4_enabled = false;
- } else {
- are_com1_com4_enabled = true;
- }
-}
-
static bool parse_printk_or_console(
const char *param,
rtems_device_minor_number *minor_out
@@ -150,6 +90,7 @@ static bool parse_printk_or_console(
size_t length;
size_t index;
rtems_device_minor_number minor;
+ console_tbl *conscfg;
/*
* Check the command line for the type of mode the console is.
@@ -198,16 +139,14 @@ static bool parse_printk_or_console(
length = &opt[index] - option;
- if ( !bsp_find_console_entry( option, length, &minor ) ) {
+ conscfg = console_find_console_entry( option, length, &minor );
+ if ( conscfg == NULL ) {
return false;
}
*minor_out = minor;
if (comma) {
- console_tbl *conscfg = &Console_Configuration_Ports[minor];
-
option = comma + 1;
-
if (strncmp (option, "115200", sizeof ("115200") - 1) == 0)
conscfg->pDeviceParams = (void *)115200;
else if (strncmp (option, "57600", sizeof ("57600") - 1) == 0)
@@ -241,39 +180,34 @@ static inline const char *get_name(
*/
void pc386_parse_console_arguments(void)
{
- rtems_device_minor_number minor;
-
- /*
- * The console device driver must have its data structures initialized
- * before we can iterate the table of devices for names.
- */
- console_initialize_data();
-
- /*
- * Determine if COM1-COM4 were disabled.
- */
- parse_com1_com4_enable();
+ rtems_device_minor_number minor;
+ rtems_device_minor_number minor_console = 0;
+ rtems_device_minor_number minor_printk = 0;
/*
* Assume that if only --console is specified, that printk() should
* follow that selection by default.
*/
if ( parse_printk_or_console( "--console=", &minor ) ) {
- Console_Port_Minor = minor;
- BSPPrintkPort = minor;
+ minor_console = minor;
+ minor_printk = minor;
}
/*
* But if explicitly specified, attempt to honor it.
*/
if ( parse_printk_or_console( "--printk=", &minor ) ) {
- BSPPrintkPort = minor;
+ minor_printk = minor;
}
-#if 0
- printk( "Console device: %s\n", get_name(Console_Port_Minor) );
- printk( "printk device: %s\n", get_name(BSPPrintkPort) );
-#endif
+ printk( "Console: %s printk: %s\n",
+ get_name(minor_console),get_name(minor_printk) );
+
+ /*
+ * Any output after this can cause problems until termios is initialised.
+ */
+ Console_Port_Minor = minor_console;
+ BSPPrintkPort = minor_printk;
}
/*
@@ -283,6 +217,10 @@ void pc386_parse_console_arguments(void)
void bsp_console_select(void)
{
#ifdef RTEMS_RUNTIME_CONSOLE_SELECT
+ /*
+ * WARNING: This code is really needed any more and should be removed.
+ * references to COM1 and COM2 like they are wrong.
+ */
if ( BSP_runtime_console_select )
BSP_runtime_console_select(&BSPPrintkPort, &Console_Port_Minor);
diff --git a/c/src/lib/libbsp/i386/pc386/console/gdb_select.c b/c/src/lib/libbsp/i386/pc386/console/gdb_select.c
new file mode 100644
index 0000000000..8e646586f6
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/console/gdb_select.c
@@ -0,0 +1,169 @@
+/**
+ * @file
+ *
+ * @ingroup GDB
+ *
+ * @brief pc386 gdb select
+ *
+ * This file contains a routine to enable and select the UART the gdb stub
+ * connects too. Currently limited to COM1 and COM2. See
+ * shared/comm/i386-stub-glue.c file.
+ */
+
+/*
+ * COPYRIGHT (c) 2016.
+ * Chris Johns <chrisj@rtems.org>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <stdlib.h>
+
+#include <bsp.h>
+#include <rtems/libio.h>
+#include <rtems/console.h>
+#include <rtems/termiostypes.h>
+#include <libchip/serial.h>
+#include <libchip/ns16550.h>
+#include <bsp/bspimpl.h>
+
+#include "../../../shared/console_private.h"
+
+/*
+ * Used in the stub to print output.
+ */
+int remote_debug;
+/*
+ * Defined in the stub, used here.
+ */
+void set_debug_traps(void);
+
+/*
+ * Added here to get a valid baudrate. Needs to go once we
+ * move to the standard UART driver.
+ */
+int BSPBaseBaud;
+
+static bool gdb_port_probe(int minor)
+{
+ /* Return false as GDB has claimed the port */
+ return false;
+}
+
+void pc386_parse_gdb_arguments(void)
+{
+ static const char *opt;
+
+ /*
+ * Check the command line to see if com1-com4 are disabled.
+ */
+ opt = bsp_cmdline_arg("--gdb=");
+ if ( opt ) {
+ const char *option;
+ const char *comma;
+ size_t length;
+ size_t index;
+ rtems_device_minor_number minor;
+ uint32_t baudrate = 115200;
+ bool halt = false;
+ console_tbl *port;
+
+ /*
+ * Fine the length, there can be more command line visible.
+ */
+ length = 0;
+ while ((opt[length] != ' ') && (opt[length] != '\0')) {
+ ++length;
+ if (length > NAME_MAX) {
+ printk("invalid option (--gdb): too long\n");
+ return;
+ }
+ }
+
+ /*
+ * Only match up to a comma or NULL
+ */
+ index = 0;
+ while ((opt[index] != '=') && (index < length)) {
+ ++index;
+ }
+
+ if (opt[index] != '=') {
+ printk("invalid option (--gdb): no equals\n");
+ return;
+ }
+
+ ++index;
+ option = &opt[index];
+
+ while ((opt[index] != ',') && (index < length)) {
+ ++index;
+ }
+
+ if (opt[index] == ',')
+ comma = &opt[index];
+ else
+ comma = NULL;
+
+ length = &opt[index] - option;
+
+ port = console_find_console_entry( option, length, &minor );
+
+ if ( port == NULL ) {
+ printk("invalid option (--gdb): port not found\n");
+ return;
+ }
+
+ if (comma) {
+ option = comma + 1;
+ baudrate = strtoul(option, 0, 10);
+ switch (baudrate) {
+ case 115200:
+ case 57600:
+ case 38400:
+ case 19200:
+ case 9600:
+ case 4800:
+ port->pDeviceParams = (void*) baudrate;
+ BSPBaseBaud = baudrate; /* REMOVE ME */
+ break;
+ default:
+ printk("invalid option (--gdb): bad baudrate\n");
+ return;
+ }
+ }
+
+ /*
+ * Provide a probe that fails so the device is not part of termios. All
+ * functions are polling.
+ */
+ port->deviceProbe = gdb_port_probe;
+ port->pDeviceFns = &ns16550_fns_polled;
+
+ opt = bsp_cmdline_arg("--gdb-remote-debug");
+ if ( opt ) {
+ remote_debug = 1;
+ }
+
+ opt = bsp_cmdline_arg("--gdb-break");
+ if ( opt ) {
+ halt = true;
+ }
+
+ printk("GDB stub: enable %s%s%s\n",
+ port->sDeviceName,
+ remote_debug ? ", remote-debug" : "",
+ halt ? ", halting" : "");
+
+ i386_stub_glue_init(minor);
+ set_debug_traps();
+ i386_stub_glue_init_breakin();
+
+ if ( halt ) {
+ printk("GDB stub: waiting for remote connection..\n");
+ breakpoint();
+ }
+ }
+}
diff --git a/c/src/lib/libbsp/i386/pc386/console/uart_bus_pci.c b/c/src/lib/libbsp/i386/pc386/console/uart_bus_pci.c
index 36afb73c46..60d35e8322 100644
--- a/c/src/lib/libbsp/i386/pc386/console/uart_bus_pci.c
+++ b/c/src/lib/libbsp/i386/pc386/console/uart_bus_pci.c
@@ -314,85 +314,88 @@ void pci_uart_probe(void)
&fun
);
if ( status == PCIB_ERR_SUCCESS ) {
+ uint8_t irq;
+ uint32_t base;
+
boards++;
conf[instance].found = true;
conf[instance].clock = pci_ns8250_ids[i].rclk;
conf[instance].ports = 1;
total_ports += conf[instance].ports;
- break;
- }
- }
-
- if ( status != PCIB_ERR_SUCCESS )
- continue;
- uint8_t irq;
- uint32_t base;
+ pci_read_config_byte( bus, dev, fun, PCI_INTERRUPT_LINE, &irq );
+ pci_read_config_dword( bus, dev, fun, PCI_BASE_ADDRESS_0, &base );
- pci_read_config_byte( bus, dev, fun, PCI_INTERRUPT_LINE, &irq );
- pci_read_config_dword( bus, dev, fun, PCI_BASE_ADDRESS_0, &base );
+ conf[instance].irq = irq;
+ conf[instance].base = base;
- conf[instance].irq = irq;
- conf[instance].base = base;
-
- printk(
- "Found %s #%d at 0x%08x IRQ %d with %d clock\n",
- pci_ns8250_ids[i].desc,
- instance,
- conf[instance].base,
- conf[instance].irq,
- conf[instance].clock
- );
+ printk(
+ "Found %s #%d at 0x%08x IRQ %d with %d clock\n",
+ pci_ns8250_ids[i].desc,
+ instance,
+ conf[instance].base,
+ conf[instance].irq,
+ conf[instance].clock
+ );
+ }
+ }
}
/*
* Now allocate array of device structures and fill them in
*/
- int device_instance;
- ports = calloc( total_ports, sizeof( console_tbl ) );
- port_p = ports;
- device_instance = 1;
- for ( b=0 ; b<MAX_BOARDS ; b++ ) {
- if ( conf[b].found == false )
- continue;
- char name[32];
-
- sprintf( name, "/dev/pcicom%d", device_instance++ );
- port_p->sDeviceName = strdup( name );
- port_p->deviceType = SERIAL_NS16550;
- if ( conf[b].irq <= 15 ) {
- port_p->pDeviceFns = &ns16550_fns;
- } else {
- printk(
- "%s IRQ=%d >= 16 requires APIC support, using polling\n",
- name,
- conf[b].irq <= 15
- );
- port_p->pDeviceFns = &ns16550_fns_polled;
- }
-
- port_p->deviceProbe = NULL;
- port_p->pDeviceFlow = NULL;
- port_p->ulMargin = 16;
- port_p->ulHysteresis = 8;
- port_p->pDeviceParams = (void *) 9600;
- port_p->ulCtrlPort1 = conf[b].base;
- port_p->ulCtrlPort2 = 0; /* NA */
- port_p->ulDataPort = 0; /* NA */
- port_p->getRegister = pci_ns16550_get_register;
- port_p->setRegister = pci_ns16550_set_register;
- port_p->getData = NULL; /* NA */
- port_p->setData = NULL; /* NA */
- port_p->ulClock = conf[b].clock;
- port_p->ulIntVector = conf[b].irq;
-
- port_p++;
- } /* end boards */
+ if (boards) {
+ int device_instance;
+
+ ports = calloc( total_ports, sizeof( console_tbl ) );
+ if (ports != NULL) {
+ port_p = ports;
+ device_instance = 1;
+ for (b = 0; b < MAX_BOARDS; b++) {
+ char name[32];
+ if ( conf[b].found == false )
+ continue;
+ sprintf( name, "/dev/pcicom%d", device_instance++ );
+ port_p->sDeviceName = strdup( name );
+ port_p->deviceType = SERIAL_NS16550;
+ if ( conf[b].irq <= 15 ) {
+ port_p->pDeviceFns = &ns16550_fns;
+ } else {
+ printk(
+ "%s IRQ=%d >= 16 requires APIC support, using polling\n",
+ name,
+ conf[b].irq
+ );
+ port_p->pDeviceFns = &ns16550_fns_polled;
+ }
- /*
- * Register the devices
- */
- if ( boards )
- console_register_devices( ports, total_ports );
+ port_p->deviceProbe = NULL;
+ port_p->pDeviceFlow = NULL;
+ port_p->ulMargin = 16;
+ port_p->ulHysteresis = 8;
+ port_p->pDeviceParams = (void *) 9600;
+ port_p->ulCtrlPort1 = conf[b].base;
+ port_p->ulCtrlPort2 = 0; /* NA */
+ port_p->ulDataPort = 0; /* NA */
+ port_p->getRegister = pci_ns16550_get_register;
+ port_p->setRegister = pci_ns16550_set_register;
+ port_p->getData = NULL; /* NA */
+ port_p->setData = NULL; /* NA */
+ port_p->ulClock = conf[b].clock;
+ port_p->ulIntVector = conf[b].irq;
+
+ port_p++;
+ } /* end boards */
+
+ /*
+ * Register the devices
+ */
+ console_register_devices( ports, total_ports );
+
+ /*
+ * Do not free the ports memory, the console hold this memory for-ever.
+ */
+ }
+ }
}
#endif
diff --git a/c/src/lib/libbsp/i386/pc386/include/bsp.h b/c/src/lib/libbsp/i386/pc386/include/bsp.h
index 34516f038a..cdfbce619e 100644
--- a/c/src/lib/libbsp/i386/pc386/include/bsp.h
+++ b/c/src/lib/libbsp/i386/pc386/include/bsp.h
@@ -197,7 +197,7 @@ void rtems_irq_mngt_init(void); /* from 'irq_init.c' */
*/
void *clock_driver_sim_idle_body(uintptr_t);
#define BSP_IDLE_TASK_BODY clock_driver_sim_idle_body
- /*
+ /*
* hack to kill some time. Hopefully hitting a hardware register is slower
* than an empty loop.
*/
@@ -255,6 +255,7 @@ void bsp_ide_cmdline_init(void);
void init_remote_gdb( void );
void i386_stub_glue_init(int uart);
void i386_stub_glue_init_breakin(void);
+int i386_stub_glue_uart(void);
void breakpoint(void);
#define BSP_MAXIMUM_DEVICES 6
diff --git a/c/src/lib/libbsp/i386/pc386/include/bspimpl.h b/c/src/lib/libbsp/i386/pc386/include/bspimpl.h
index 6503e0a0e2..314fb91eb9 100644
--- a/c/src/lib/libbsp/i386/pc386/include/bspimpl.h
+++ b/c/src/lib/libbsp/i386/pc386/include/bspimpl.h
@@ -1,7 +1,7 @@
/**
* @file
*
- * BSP specific helpers
+ * BSP specific helpers
*/
/*
@@ -30,6 +30,16 @@ const pci_config_access_functions *pci_io_initialize(void);
void pc386_parse_console_arguments(void);
/*
+ * Helper to parse boot command line arguments related to gdb
+ */
+void pc386_parse_gdb_arguments(void);
+
+/*
+ * Dynamically probe for Legacy UARTS
+ */
+void legacy_uart_probe(void);
+
+/*
* Dynamically probe for PCI UARTS
*/
void pci_uart_probe(void);
diff --git a/c/src/lib/libbsp/i386/pc386/startup/bspstart.c b/c/src/lib/libbsp/i386/pc386/startup/bspstart.c
index 41f858b5d0..0559fbe065 100644
--- a/c/src/lib/libbsp/i386/pc386/startup/bspstart.c
+++ b/c/src/lib/libbsp/i386/pc386/startup/bspstart.c
@@ -10,6 +10,9 @@
* It was subsequently adapted as part of the pc386 BSP by developers from
* the NavIST Group in 1997.
*
+ * Copyright (c) 2016.
+ * Chris Johns <chrisj@rtems.org>
+ *
* COPYRIGHT (c) 1989-2008, 2016.
* On-Line Applications Research Corporation (OAR).
*
@@ -107,16 +110,29 @@ static void bsp_start_default( void )
bsp_pci_initialize_helper();
/*
- * Probe for UARTs on PCI. One of these may end up as the console.
+ * Probe for legacy UARTs.
+ */
+ legacy_uart_probe();
+
+ /*
+ * Probe for UARTs on PCI.
*/
pci_uart_probe();
/*
- * Figure out where printk() and console IO is to be directed.
- * Do this after the PCI bus is initialized so we have a chance
- * for those devices to be added to the set in the console driver.
- * In general, Do it as early as possible so printk() has a chance
- * to work early on devices found via PCI probe.
+ * Parse the GDB arguments and flag a serial port as not valid. This stops
+ * the console from claming the port.
+ */
+#if BSP_GDB_STUB
+ pc386_parse_gdb_arguments();
+#endif
+
+ /*
+ * Figure out where printk() and console IO is to be directed. Do this after
+ * the legacy and PCI bus probes so we have a chance for those devices to be
+ * added to the set in the console driver. In general, do it as early as
+ * possible so printk() has a chance to work early on devices found via PCI
+ * probe.
*/
pc386_parse_console_arguments();
@@ -127,7 +143,6 @@ static void bsp_start_default( void )
#if BSP_ENABLE_IDE
bsp_ide_cmdline_init();
#endif
-
} /* bsp_start_default */
/*
diff --git a/c/src/lib/libbsp/i386/pc386/startup/ldsegs.S b/c/src/lib/libbsp/i386/pc386/startup/ldsegs.S
index 82ff982331..ea41874a1b 100644
--- a/c/src/lib/libbsp/i386/pc386/startup/ldsegs.S
+++ b/c/src/lib/libbsp/i386/pc386/startup/ldsegs.S
@@ -110,7 +110,6 @@ next_step:
movw ax, fs
movw ax, gs
-#if (BSP_IS_EDISON == 0)
/*---------------------------------------------------------------------+
| Now we have to reprogram the interrupts :-(. We put them right after
| the intel-reserved hardware interrupts, at int 0x20-0x2F. There they
@@ -121,6 +120,7 @@ next_step:
| it isn't fun.
+---------------------------------------------------------------------*/
+#if (BSP_IS_EDISON == 0)
movb $0x11, al /* initialization sequence */
outb al, $0x20 /* send it to 8259A-1 */
call SYM(pc386_delay)