[PATCH 1/3] i386/pc386: Add support for the gdb stub to use available console drivers.
Joel Sherrill
joel at rtems.org
Wed Apr 20 23:01:19 UTC 2016
On Wed, Apr 20, 2016 at 2:20 AM, Chris Johns <chrisj at rtems.org> wrote:
> 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.
> ---
> c/src/lib/libbsp/i386/pc386/Makefile.am | 5 +-
> c/src/lib/libbsp/i386/pc386/README | 23 ++-
> c/src/lib/libbsp/i386/pc386/configure.ac | 6 +
> c/src/lib/libbsp/i386/pc386/console/conscfg.c | 88 ++++++----
> .../libbsp/i386/pc386/console/console_control.c | 39 +++--
> .../lib/libbsp/i386/pc386/console/console_select.c | 106 +++--------
> c/src/lib/libbsp/i386/pc386/console/gdb_select.c | 169
> ++++++++++++++++++
> c/src/lib/libbsp/i386/pc386/console/uart_bus_pci.c | 135 +++++++-------
> c/src/lib/libbsp/i386/pc386/include/bsp.h | 3 +-
> c/src/lib/libbsp/i386/pc386/include/bspimpl.h | 12 +-
> c/src/lib/libbsp/i386/pc386/startup/bspstart.c | 29 ++-
> c/src/lib/libbsp/i386/pc386/startup/ldsegs.S | 2 +-
> c/src/lib/libbsp/i386/shared/comm/GDB.HOWTO | 134 +++++++-------
> c/src/lib/libbsp/i386/shared/comm/i386-stub-glue.c | 195
> ++++++++++++++-------
> c/src/lib/libbsp/i386/shared/comm/i386-stub.c | 179
> +++++++++++--------
> c/src/lib/libbsp/shared/console.c | 43 ++++-
> c/src/lib/libbsp/shared/console_private.h | 13 ++
> 17 files changed, 754 insertions(+), 427 deletions(-)
> create mode 100644 c/src/lib/libbsp/i386/pc386/console/gdb_select.c
>
> diff --git a/c/src/lib/libbsp/i386/pc386/Makefile.am
> b/c/src/lib/libbsp/i386/pc386/Makefile.am
> index d9af7dd..22d4bf1 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 bfebf19..4ed8829 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
>
>
What is the aaa?
> -+ 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 17b7d02..d62a9b3 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 5b7ebc5..82d3cf9 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 a0b9220..3a454d9 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 6a91a96..f7e6bbc 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 0000000..8e64658
> --- /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 at 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;
> + }
> + }
>
Is there anyway the code parsing this option can be shared with that
for the com ports?
> + /*
> + * 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 36afb73..60d35e8 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 34516f0..cdfbce6 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 6503e0a..314fb91 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 41f858b..0559fbe 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 at 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 82ff982..ea41874 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)
> diff --git a/c/src/lib/libbsp/i386/shared/comm/GDB.HOWTO
> b/c/src/lib/libbsp/i386/shared/comm/GDB.HOWTO
> index c57f5a5..d5e0326 100644
> --- a/c/src/lib/libbsp/i386/shared/comm/GDB.HOWTO
> +++ b/c/src/lib/libbsp/i386/shared/comm/GDB.HOWTO
> @@ -1,30 +1,31 @@
> -1. Add GDB initilization to your target's code:
> +i386/pc386 GDB Stub
>
> -a) include file:
> +The i386 GDB stub has been updated to use the libchip drivers for the
> +NS16550. Make sure you have detect the device and you have added a console
> +entry. On the PC the legacy and PCI boards are supported.
>
> -#include <uart.h>
> +This GDB stub glue code is specific to the UART protocol defined in
> libbchip.
>
> -b) declare this variable:
> +The pc386 BSP has boot command line options to manage GDB support.
>
> -extern int BSPConsolePort;
> +a) Find the minor number of the console device:
>
> -c) To start-up GDB, run this:
> + #include <console_private.h>
>
> - /* Init GDB glue */
> + rtems_device_minor_number minor = 0;
>
> - 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);
> - }
> + if (console_find_console_entry("/dev/com1",
> + strlen("/dev/com1") - 1, &minor) == NULL)
> + error("driver not found\n");
> +
> +Note, this call is part of the private console API and may change.
> +
> +b) To start GDB stub, run this:
> +
> + #include <bsp.h>
> +
> + /* Init GDB glue */
> + i386_stub_glue_init(minor);
>
> /* Init GDB stub itself */
> set_debug_traps();
> @@ -39,54 +40,45 @@ c) To start-up GDB, run this:
> /* 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 ==============================
> -/usr1/rtems/work/rtems/cpukit/ada
> -/usr1/rtems/work/rtems/cpukit/libblock/src
> -/usr1/rtems/work/rtems/cpukit/libcsupport/src
> -/usr1/rtems/work/rtems/cpukit/libfs/src/dosfs
> -/usr1/rtems/work/rtems/cpukit/libfs/src/imfs
> -/usr1/rtems/work/rtems/cpukit/libmisc/capture
> -/usr1/rtems/work/rtems/cpukit/libmisc/cpuuse
> -/usr1/rtems/work/rtems/cpukit/libmisc/devnull
> -/usr1/rtems/work/rtems/cpukit/libmisc/dummy
> -/usr1/rtems/work/rtems/cpukit/libmisc/dumpbuf
> -/usr1/rtems/work/rtems/cpukit/libmisc/monitor
> -/usr1/rtems/work/rtems/cpukit/libmisc/mw-fb
> -/usr1/rtems/work/rtems/cpukit/libmisc/rtmonuse
> -/usr1/rtems/work/rtems/cpukit/libmisc/serdbg
> -/usr1/rtems/work/rtems/cpukit/libmisc/shell
> -/usr1/rtems/work/rtems/cpukit/libmisc/stackchk
> -/usr1/rtems/work/rtems/cpukit/libmisc/untar
> -/usr1/rtems/work/rtems/cpukit/libnetworking/arpa
> -/usr1/rtems/work/rtems/cpukit/libnetworking/kern
> -/usr1/rtems/work/rtems/cpukit/libnetworking/lib
> -/usr1/rtems/work/rtems/cpukit/libnetworking/libc
> -/usr1/rtems/work/rtems/cpukit/libnetworking/machine
> -/usr1/rtems/work/rtems/cpukit/libnetworking/net
> -/usr1/rtems/work/rtems/cpukit/libnetworking/netinet
> -/usr1/rtems/work/rtems/cpukit/libnetworking/nfs
> -/usr1/rtems/work/rtems/cpukit/libnetworking/rtems
> -/usr1/rtems/work/rtems/cpukit/libnetworking/sys
> -/usr1/rtems/work/rtems/cpukit/libnetworking/vm
> -/usr1/rtems/work/rtems/cpukit/librpc/src/rpc
> -/usr1/rtems/work/rtems/cpukit/librpc/src/xdr
> -/usr1/rtems/work/rtems/cpukit/posix/src
> -/usr1/rtems/work/rtems/cpukit/posix/inline/rtems/posix
> -/usr1/rtems/work/rtems/cpukit/rtems/inline/rtems/rtems
> -/usr1/rtems/work/rtems/cpukit/rtems/src
> -/usr1/rtems/work/rtems/cpukit/sapi/inline/rtems
> -/usr1/rtems/work/rtems/cpukit/sapi/src
> -/usr1/rtems/work/rtems/cpukit/score/cpu/i386
> -/usr1/rtems/work/rtems/cpukit/score/cpu/i386/rtems/score
> -/usr1/rtems/work/rtems/cpukit/score/src
> -/usr1/rtems/work/rtems/cpukit/score/inline/rtems/score
> -set remotebaud 38400
> -target remote /dev/ttyS1
> +c) To run use GDB:
> +
> + $ i386-rtems4.12-gdb hello.exe
> + GNU gdb (GDB) 7.11
> + Copyright (C) 2016 Free Software Foundation, Inc.
> + License GPLv3+: GNU GPL version 3 or later <
> http://gnu.org/licenses/gpl.html>
> + This is free software: you are free to change and redistribute it.
> + There is NO WARRANTY, to the extent permitted by law. Type "show
> copying"
> + and "show warranty" for details.
> + This GDB was configured as "--host=x86_64-freebsd10.1
> --target=i386-rtems4.12".
> + Type "show configuration" for configuration details.
> + For bug reporting instructions, please see:
> + <http://www.gnu.org/software/gdb/bugs/>.
> + Find the GDB manual and other documentation resources online at:
> + <http://www.gnu.org/software/gdb/documentation/>.
> + For help, type "help".
> + Type "apropos word" to search for commands related to "word"...
> + Reading symbols from hello.exe...done.
> + (gdb) target remote /dev/cuaU5
> + Remote debugging using /dev/cuaU5
> + 0x00103fda in breakpoint () at i386-stub.c:1004
> + 1004 BREAKPOINT ();
> + (gdb) b Init
> + Breakpoint 1 at 0x1001e0: file init.c, line 29.
> + (gdb) c
> + Continuing.
> +
> + Breakpoint 1, Init (ignored=1269800) at init.c:29
> + 29 {
> + (gdb)
> +
> +Pressing ^C works and if running the board should halt when GDB connects.
> +
> +e) Use ser2net to provide reomve access over a network to a board.
> Install the
> +ser2net package and add a configuration for the port GDB connects to. For
> +example:
> +
> + 0005:raw:0:/dev/cuaU5:115200
> +
> +Start ser2net running then connect GDB using:
> +
> + (gdb) target remote myhost:30005
> 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
> index 121eef1..25a153f 100644
> --- a/c/src/lib/libbsp/i386/shared/comm/i386-stub-glue.c
> +++ b/c/src/lib/libbsp/i386/shared/comm/i386-stub-glue.c
> @@ -1,23 +1,102 @@
> /*
> + * Copyright (c) 2016.
> + * Chris Johns <chrisj at rtems.org>
> + *
> * 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.
> */
>
> -#include <rtems/system.h>
> -#include <rtems/score/cpu.h>
> #include <bsp.h>
> #include <bsp/irq.h>
> -#include <uart.h>
> -#include <assert.h>
> +#include <libchip/serial.h>
> +
> +#include "../../../shared/console_private.h"
>
> int putDebugChar(int ch); /* write a single character */
> int getDebugChar(void); /* read and return a single char */
>
> +/* Check is any characters received are a ^C */
> +int i386_gdb_uart_ctrl_c_check(void);
> +
> +/* Raw interrupt handler. */
> +void i386_gdb_uart_isr(void);
> +
> /* assign an exception handler */
> void exceptionHandler(int, void (*handler)(void));
>
> +/* User supplied remote debug option. */
> +extern int remote_debug;
> +
> +/* Current uart and port used by the gdb stub */
> +static int uart_current;
> +static console_tbl* port_current;
> +
> +/*
> + * Interrupt service routine for 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.
> + *
> + * Warning: I do not like the use of the global data, I am not
> + * sure if this is SMP safe.
> + */
> +int i386_gdb_uart_isr_regsav[4] RTEMS_UNUSED;
> +__asm__ (".p2align 4");
> +__asm__ (".text");
> +__asm__ (".globl i386_gdb_uart_isr");
> +__asm__ ("i386_gdb_uart_isr:");
> +__asm__ (" pusha"); /* Push all
> */
> +__asm__ (" call i386_gdb_uart_ctrl_c_check"); /* Look for
> ^C */
> +__asm__ (" movl %eax, i386_gdb_uart_isr_regsav"); /* Save eax
> */
> +__asm__ (" popa"); /* Pop all */
> +__asm__ (" xchgl %eax, i386_gdb_uart_isr_regsav"); /* Exchange
> eax */
> +__asm__ (" cmpl $0, %eax"); /* 1 == ^C */
> +__asm__ (" je i386_gdb_uart_isr_1"); /* branch if
> 0 */
> +__asm__ (" movl %ebx, i386_gdb_uart_isr_regsav + 4"); /* Save ebx
> */
> +__asm__ (" movl %edx, i386_gdb_uart_isr_regsav + 8"); /* Save edx
> */
> +__asm__ (" popl %ebx"); /* Pop eip */
> +__asm__ (" popl %edx"); /* Pop cs */
> +__asm__ (" popl %eax"); /* Pop flags
> */
> +__asm__ (" orl $0x100, %eax"); /* Modify it
> */
> +__asm__ (" pushl %eax"); /* Push it
> back */
> +__asm__ (" pushl %edx"); /* Push cs */
> +__asm__ (" pushl %ebx"); /* Push eip
> */
> +__asm__ (" movl i386_gdb_uart_isr_regsav + 4, %ebx"); /* Restore
> ebx */
> +__asm__ (" movl i386_gdb_uart_isr_regsav + 8, %edx"); /* Restore
> edx */
> +__asm__ ("i386_gdb_uart_isr_1:");
> +__asm__ (" movb $0x20, %al");
> +__asm__ (" outb %al, $0x20");
> +__asm__ (" movl i386_gdb_uart_isr_regsav, %eax"); /* Restore
> eax */
> +__asm__ (" iret"); /* Done */
> +
> +static int gdb_hello_index;
> +static const char const* gdb_hello = "+";
> +
> +int i386_gdb_uart_ctrl_c_check(void)
> +{
> + if (port_current) {
> + int c = 0;
> + while (c >= 0) {
> + c = port_current->pDeviceFns->deviceRead(uart_current);
> + if (c == 3) {
> + gdb_hello_index = 0;
> + return 1;
> + } else if (gdb_hello[gdb_hello_index] == (char) c) {
> + ++gdb_hello_index;
> + if (gdb_hello[gdb_hello_index] == '\0') {
> + gdb_hello_index = 0;
> + return 1;
> + }
> + } else {
> + gdb_hello_index = 0;
> + }
> + }
> + }
> + return 0;
> +}
> +
> static void
> nop(const rtems_raw_irq_connect_data* notused)
> {
> @@ -29,10 +108,12 @@ isOn(const rtems_raw_irq_connect_data* notused)
> return 1;
> }
>
> -void BSP_loop(int uart);
> -
> -/* Current uart used by gdb stub */
> -static int uart_current = 0;
> +int i386_stub_glue_uart(void)
> +{
> + if (port_current == NULL)
> + return -1;
> + return uart_current;
> +}
>
> /*
> * Initialize glue code linking i386-stub with the rest of
> @@ -41,12 +122,19 @@ static int uart_current = 0;
> void
> i386_stub_glue_init(int uart)
> {
> - assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
> + rtems_device_minor_number minor = (rtems_device_minor_number) uart;
> +
> + port_current = console_find_console_entry(NULL, 0, &minor);
> +
> + if (port_current == NULL) {
> + printk("GDB: invalid minor number for UART\n");
> + return;
> + }
>
> uart_current = uart;
>
> - /* BSP_uart_init(uart, 38400, CHR_8_BITS, 0, 0, 0);*/
> - BSP_uart_init(uart, 115200, CHR_8_BITS, 0, 0, 0);
> + /* Intialise the UART, assuming polled drivers */
> + port_current->pDeviceFns->deviceInitialize(uart);
> }
>
> static void BSP_uart_on(const rtems_raw_irq_connect_data* used)
> @@ -72,76 +160,65 @@ 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 (port_current == NULL) {
> + printk("GDB: no port initialised\n");
> + return;
> + }
>
> - 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 ((port_current->ulIntVector == 0) || (port_current->ulIntVector >
> 16)) {
> + printk("GDB: no UART interrupt support\n");
> + }
> + else {
> + uart_raw_irq_data.idtIndex = port_current->ulIntVector +
> BSP_IRQ_VECTOR_BASE;
>
> - if(!i386_get_current_idt_entry(&uart_raw_irq_data))
> - {
> - printk("cannot get idt entry\n");
> + if (!i386_get_current_idt_entry(&uart_raw_irq_data)) {
> + printk("GBD: 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");
> + if (!i386_delete_idt_entry(&uart_raw_irq_data)) {
> + printk("GDB: 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;
> + 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;
> - }
> + /* Install ISR */
> + uart_raw_irq_data.idtIndex = port_current->ulIntVector +
> BSP_IRQ_VECTOR_BASE;
> + uart_raw_irq_data.hdl = i386_gdb_uart_isr;
>
> - if (!i386_set_idt_entry (&uart_raw_irq_data))
> - {
> - printk("raw exception handler connection failed\n");
> + if (!i386_set_idt_entry (&uart_raw_irq_data)) {
> + printk("GDB: 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;
> + /* Enable interrupts, this is a bit of a hack because we
> + * have to know the device but there is no other call. */
> + (*port_current->setRegister)(port_current->ulCtrlPort1, 1, 0x01);
> + }
> }
>
> int
> putDebugChar(int ch)
> {
> - assert(uart_current == BSP_UART_COM1 || uart_current == BSP_UART_COM2);
> -
> - BSP_uart_polled_write(uart_current, ch);
> -
> + if (port_current != NULL) {
> + port_current->pDeviceFns->deviceWritePolled(uart_current, ch);
> + }
> return 1;
> }
>
> int getDebugChar(void)
> {
> - int val;
> -
> - assert(uart_current == BSP_UART_COM1 || uart_current == BSP_UART_COM2);
> + int c = -1;
>
> - val = BSP_uart_polled_read(uart_current);
> + if (port_current != NULL) {
> + while (c < 0)
> + c = port_current->pDeviceFns->deviceRead(uart_current);
> + }
>
> - return val;
> + return c;
> }
>
> void exceptionHandler(int vector, void (*handler)(void))
> @@ -152,13 +229,13 @@ void exceptionHandler(int vector, void
> (*handler)(void))
>
> if(!i386_get_current_idt_entry(&excep_raw_irq_data))
> {
> - printk("cannot get idt entry\n");
> + printk("GDB: 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");
> + printk("GDB: cannot delete idt entry\n");
> rtems_fatal_error_occurred(1);
> }
>
> @@ -168,7 +245,7 @@ void exceptionHandler(int vector, void
> (*handler)(void))
> excep_raw_irq_data.hdl = handler;
>
> if (!i386_set_idt_entry (&excep_raw_irq_data)) {
> - printk("raw exception handler connection failed\n");
> + printk("GDB: 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
> index bc72396..b3630ee 100644
> --- a/c/src/lib/libbsp/i386/shared/comm/i386-stub.c
> +++ b/c/src/lib/libbsp/i386/shared/comm/i386-stub.c
> @@ -99,6 +99,8 @@
> #include <string.h>
> #include <stdbool.h>
>
> +#include <bsp.h>
> +
> /*
> * Prototypes we need to avoid warnings but not going into public space.
> */
> @@ -150,11 +152,15 @@ enum regnames
> /*
> * these should not be static cuz they can be used outside this module
> */
> -int registers[NUMREGS];
> +
> +int i386_gdb_registers[NUMREGS];
>
> #define STACKSIZE 10000
> -int remcomStack[STACKSIZE / sizeof (int)];
> -static int *stackPtr = &remcomStack[STACKSIZE / sizeof (int) - 1];
> +int i386_gdb_remcomStack[STACKSIZE / sizeof (int)];
> +int *i386_gdb_stackPtr = &i386_gdb_remcomStack[STACKSIZE / sizeof (int) -
> 1];
> +
> +
> +static int gdb_connected;
>
> /*************************** ASSEMBLY CODE MACROS
> *************************/
> /*
> */
> @@ -168,25 +174,25 @@ extern void
> __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__ (" movw i386_gdb_registers+44, %ss");
> +__asm__ (" movl i386_gdb_registers+16, %esp");
> +__asm__ (" movl i386_gdb_registers+4, %ecx");
> +__asm__ (" movl i386_gdb_registers+8, %edx");
> +__asm__ (" movl i386_gdb_registers+12, %ebx");
> +__asm__ (" movl i386_gdb_registers+20, %ebp");
> +__asm__ (" movl i386_gdb_registers+24, %esi");
> +__asm__ (" movl i386_gdb_registers+28, %edi");
> +__asm__ (" movw i386_gdb_registers+48, %ds");
> +__asm__ (" movw i386_gdb_registers+52, %es");
> +__asm__ (" movw i386_gdb_registers+56, %fs");
> +__asm__ (" movw i386_gdb_registers+60, %gs");
> +__asm__ (" movl i386_gdb_registers+36, %eax");
> __asm__ (" pushl %eax"); /* saved eflags */
> -__asm__ (" movl registers+40, %eax");
> +__asm__ (" movl i386_gdb_registers+40, %eax");
> __asm__ (" pushl %eax"); /* saved cs */
> -__asm__ (" movl registers+32, %eax");
> +__asm__ (" movl i386_gdb_registers+32, %eax");
> __asm__ (" pushl %eax"); /* saved eip */
> -__asm__ (" movl registers, %eax");
> +__asm__ (" movl i386_gdb_registers, %eax");
> /* use iret to restore pc and flags together so
> that trace flag works right. */
> __asm__ (" iret");
> @@ -202,37 +208,37 @@ 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");
> + __asm__ ("movl %eax, i386_gdb_registers"); \
> + __asm__ ("movl %ecx, i386_gdb_registers+4"); \
> + __asm__ ("movl %edx, i386_gdb_registers+8"); \
> + __asm__ ("movl %ebx, i386_gdb_registers+12");
> \
> + __asm__ ("movl %ebp, i386_gdb_registers+20");
> \
> + __asm__ ("movl %esi, i386_gdb_registers+24");
> \
> + __asm__ ("movl %edi, i386_gdb_registers+28");
> \
> + __asm__ ("movw $0, %ax"); \
> + __asm__ ("movw %ds, i386_gdb_registers+48"); \
> + __asm__ ("movw %ax, i386_gdb_registers+50"); \
> + __asm__ ("movw %es, i386_gdb_registers+52"); \
> + __asm__ ("movw %ax, i386_gdb_registers+54"); \
> + __asm__ ("movw %fs, i386_gdb_registers+56"); \
> + __asm__ ("movw %ax, i386_gdb_registers+58"); \
> + __asm__ ("movw %gs, i386_gdb_registers+60"); \
> + __asm__ ("movw %ax, i386_gdb_registers+62");
> #define SAVE_ERRCODE() \
> - __asm__ ("popl %ebx"); \
> + __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");
> + __asm__ ("popl %ebx"); /* old eip */ \
> + __asm__ ("movl %ebx, i386_gdb_registers+32");
> \
> + __asm__ ("popl %ebx"); /* old cs */ \
> + __asm__ ("movl %ebx, i386_gdb_registers+40");
> \
> + __asm__ ("movw %ax, i386_gdb_registers+42"); \
> + __asm__ ("popl %ebx"); /* old eflags */ \
> + __asm__ ("movl %ebx, i386_gdb_registers+36");
> \
> + /* Now that we've done the pops, we can save the stack pointer."); */ \
> + __asm__ ("movw %ss, i386_gdb_registers+44"); \
> + __asm__ ("movw %ax, i386_gdb_registers+46"); \
> + __asm__ ("movl %esp, i386_gdb_registers+16");
>
> /* See if mem_fault_routine is set, if so just IRET to that address. */
> #define CHECK_FAULT() \
> @@ -449,7 +455,7 @@ extern void remcomHandler (void);
> __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__ (" movl i386_gdb_stackPtr, %esp"); /* move to remcom
> stack area */
> __asm__ (" pushl %eax"); /* push exception onto stack */
> __asm__ (" call handle_exception"); /* this never
> returns */
>
> @@ -508,10 +514,15 @@ getpacket (char *buffer)
> 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);
> + printk ("bad checksum. My count = 0x%x, sent=0x%x.
> buf=%s\n",
> + checksum, xmitcsum, buffer);
> }
>
> + if (remote_debug) {
> + printk("GETP: $%s...%s\n", buffer,
> + checksum == xmitcsum ? "Ack" : "Nack");
> + }
> +
> if (checksum != xmitcsum)
> putDebugChar ('-'); /* failed checksum */
> else
> @@ -539,13 +550,16 @@ getpacket (char *buffer)
> static void
> putpacket (char *buffer)
> {
> - unsigned char checksum;
> - int count;
> - char ch;
> -
> /* $<packet info>#<checksum>. */
> - do
> + while (true)
> {
> + unsigned char checksum;
> + int count;
> + char ch;
> +
> + if (remote_debug)
> + printk("PUTP: $%s", buffer);
> +
> putDebugChar ('$');
> checksum = 0;
> count = 0;
> @@ -562,9 +576,18 @@ putpacket (char *buffer)
> putDebugChar (hexchars[checksum >> 4]);
> putDebugChar (hexchars[checksum % 16]);
>
> - }
> - while ((getDebugChar () & 0x7f) != '+');
> + if (remote_debug)
> + printk("#%c%c...", hexchars[checksum >> 4], hexchars[checksum %
> 16]);
>
> + ch = getDebugChar () & 0x7f;
> + if (ch == '+') {
> + if (remote_debug)
> + printk("Ack\n");
> + break;
> + }
> + if (remote_debug)
> + printk("Nack(%c)\n", ch);
> + }
> }
>
> char remcomInBuffer[BUFMAX];
> @@ -578,7 +601,7 @@ debug_error (
> )
> {
> if (remote_debug)
> - fprintf (stderr, format, parm);
> + printk (format, parm);
> }
>
> /* Address of a routine to RTE to if we get a memory fault. */
> @@ -764,10 +787,10 @@ handle_exception (int exceptionVector)
> gdb_i386vector = exceptionVector;
>
> if (remote_debug)
> - printf ("vector=%d, sr=0x%x, pc=0x%x\n",
> + printk ("GDB: EXECPTION: vector=%d, sr=0x%x, pc=0x%x\n",
> exceptionVector,
> - registers[PS],
> - registers[PC]);
> + i386_gdb_registers[PS],
> + i386_gdb_registers[PC]);
>
> /* Reply to host that an exception has occurred. Always return the
> PC, SP, and FP, since gdb always wants them. */
> @@ -779,31 +802,33 @@ handle_exception (int exceptionVector)
>
> *ptr++ = hexchars[ESP];
> *ptr++ = ':';
> - mem2hex ((char *) ®isters[ESP], ptr, REGBYTES, 0);
> + mem2hex ((char *) &i386_gdb_registers[ESP], ptr, REGBYTES, 0);
> ptr += REGBYTES * 2;
> *ptr++ = ';';
>
> *ptr++ = hexchars[EBP];
> *ptr++ = ':';
> - mem2hex ((char *) ®isters[EBP], ptr, REGBYTES, 0);
> + mem2hex ((char *) &i386_gdb_registers[EBP], ptr, REGBYTES, 0);
> ptr += REGBYTES * 2;
> *ptr++ = ';';
>
> *ptr++ = hexchars[PC];
> *ptr++ = ':';
> - mem2hex ((char *) ®isters[PC], ptr, REGBYTES, 0);
> + mem2hex ((char *) &i386_gdb_registers[PC], ptr, REGBYTES, 0);
> ptr += REGBYTES * 2;
> *ptr++ = ';';
>
> *ptr = '\0';
>
> - putpacket (remcomOutBuffer);
> + if (gdb_connected)
> + putpacket (remcomOutBuffer);
>
> while (1 == 1)
> {
> error = 0;
> remcomOutBuffer[0] = 0;
> getpacket (remcomInBuffer);
> + gdb_connected = 1;
> switch (remcomInBuffer[0])
> {
> case '?':
> @@ -812,14 +837,14 @@ handle_exception (int exceptionVector)
> remcomOutBuffer[2] = hexchars[sigval % 16];
> remcomOutBuffer[3] = 0;
> break;
> - case 'd':
> + case 'd': /* remove */
> remote_debug = !(remote_debug); /* toggle debug flag */
> break;
> case 'g': /* return the value of the CPU registers */
> - mem2hex ((char *) registers, remcomOutBuffer, NUMREGBYTES, 0);
> + mem2hex ((char *) i386_gdb_registers, remcomOutBuffer,
> NUMREGBYTES, 0);
> break;
> case 'G': /* set the value of the CPU registers -
> return OK */
> - hex2mem (&remcomInBuffer[1], (char *) registers, NUMREGBYTES, 0);
> + hex2mem (&remcomInBuffer[1], (char *) i386_gdb_registers,
> NUMREGBYTES, 0);
> strcpy (remcomOutBuffer, "OK");
> break;
>
> @@ -828,7 +853,7 @@ handle_exception (int exceptionVector)
> if (hexToInt (&ptr, ®)
> && *ptr++ == '=')
> {
> - hex2mem (ptr, (char *) ®isters[reg], REGBYTES, 0);
> + hex2mem (ptr, (char *) &i386_gdb_registers[reg], REGBYTES,
> 0);
> strcpy (remcomOutBuffer, "OK");
> }
> else
> @@ -902,29 +927,31 @@ handle_exception (int exceptionVector)
> /* try to read optional parameter, pc unchanged if no parm */
> ptr = &remcomInBuffer[1];
> if (hexToInt (&ptr, &addr))
> - registers[PC] = addr;
> + i386_gdb_registers[PC] = addr;
>
> /* clear the trace bit */
> - registers[PS] &= 0xfffffeff;
> + i386_gdb_registers[PS] &= 0xfffffeff;
>
> /* set the trace bit if we're stepping */
> if (remcomInBuffer[0] == 's')
> - registers[PS] |= 0x100;
> + i386_gdb_registers[PS] |= 0x100;
>
> _returnFromException (); /* this is a jump */
> -
> break;
>
> /* Detach. */
> case 'D':
> putpacket (remcomOutBuffer);
> - registers[PS] &= 0xfffffeff;
> + i386_gdb_registers[PS] &= 0xfffffeff;
> _returnFromException (); /* this is a jump */
> -
> break;
>
> /* kill the program */
> case 'k': /* do nothing */
> + bsp_reset();
> + continue;
> +
> + default:
> break;
> } /* switch */
>
> @@ -938,7 +965,7 @@ handle_exception (int exceptionVector)
> void
> set_debug_traps (void)
> {
> - stackPtr = &remcomStack[STACKSIZE / sizeof (int) - 1];
> + i386_gdb_stackPtr = &i386_gdb_remcomStack[STACKSIZE / sizeof (int) - 1];
>
> exceptionHandler (0, _catchException0);
> exceptionHandler (1, _catchException1);
> diff --git a/c/src/lib/libbsp/shared/console.c
> b/c/src/lib/libbsp/shared/console.c
> index d226172..b4af1b3 100644
> --- a/c/src/lib/libbsp/shared/console.c
> +++ b/c/src/lib/libbsp/shared/console.c
> @@ -34,6 +34,45 @@ rtems_device_minor_number Console_Port_Minor = 0;
> static bool console_initialized = false;
>
> /*
> + * console_find_console_entry
> + *
> + * This method is used to search the console entries for a
> + * specific device entry.
> + */
> +console_tbl* console_find_console_entry(
> + const char *match,
> + size_t length,
> + rtems_device_minor_number *match_minor
> +)
> +{
> + rtems_device_minor_number minor;
> +
> + /*
> + * The the match name is NULL get the minor number entry.
> + */
> + if (match == NULL) {
> + if (*match_minor < Console_Port_Count)
> + return Console_Port_Tbl[*match_minor];
> + return NULL;
> + }
> +
> + 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.
> + */
> + if ( !strncmp( cptr->sDeviceName, match, length ) ) {
> + *match_minor = minor;
> + return cptr;
> + }
> + }
> +
> + return NULL;
> +}
> +
> +/*
> * console_initialize_data
> *
> * This method is used to initialize the table of pointers to the
> @@ -278,9 +317,7 @@ rtems_device_driver console_initialize(
> * must still initialize pointers for Console_Port_Tbl and
> * Console_Port_Data.
> */
> - if ( !Console_Port_Tbl ) {
> - console_initialize_data();
> - }
> + console_initialize_data();
>
> /*
> * console_initialize has been invoked so it is now too late to
> diff --git a/c/src/lib/libbsp/shared/console_private.h
> b/c/src/lib/libbsp/shared/console_private.h
> index 42a8ee9..3855e83 100644
> --- a/c/src/lib/libbsp/shared/console_private.h
> +++ b/c/src/lib/libbsp/shared/console_private.h
> @@ -41,6 +41,19 @@ int vt_ioctl(
> );
>
> /**
> + * @brief console_find_console_entry
> + *
> + * This method is used to search the console entries for a
> + * specific device entry and return it. If match is NULL the
> + * minor number provided is matched.
> + */
> +console_tbl* console_find_console_entry(
> + const char *match,
> + size_t length,
> + rtems_device_minor_number *match_minor
> +);
> +
> +/**
> * @brief console_initialize_data
> *
> * This must be called before dynamic registration of devices can occur.
> --
> 2.4.6
>
> _______________________________________________
> devel mailing list
> devel at rtems.org
> http://lists.rtems.org/mailman/listinfo/devel
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/devel/attachments/20160420/9ee57f9f/attachment-0002.html>
More information about the devel
mailing list