summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp
diff options
context:
space:
mode:
authorJoel Sherrill <joel@rtems.org>2016-03-10 10:33:27 -0600
committerJoel Sherrill <joel@rtems.org>2016-03-10 10:33:27 -0600
commitc3c57b1ba3c945efea3bc24d71728b6c1e40f421 (patch)
tree328a8255e8825a53a83e548273c6172941193452 /c/src/lib/libbsp
parentAdd shared PCI support and enhance pc386 to support non-legacy PCI configurat... (diff)
downloadrtems-c3c57b1ba3c945efea3bc24d71728b6c1e40f421.tar.bz2
pc386: Improve boot command arguments for console/printk device selection
This patch adds the "--printk=" boot command line argument to specify the printk() device. It also enhances the "--console=" boot command line argument to match any device configured in the console device table. The arguments are parsed as early as possible so they take effect early. Currently, this is immediately after PCI initialization.
Diffstat (limited to '')
-rw-r--r--c/src/lib/libbsp/i386/pc386/console/console_select.c180
-rw-r--r--c/src/lib/libbsp/i386/pc386/include/bsp.h6
-rw-r--r--c/src/lib/libbsp/i386/pc386/startup/bspstart.c9
-rw-r--r--c/src/lib/libbsp/shared/console.c8
-rw-r--r--c/src/lib/libbsp/shared/console_private.h12
5 files changed, 171 insertions, 44 deletions
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 3a756b4799..c78b4b89bf 100644
--- a/c/src/lib/libbsp/i386/pc386/console/console_select.c
+++ b/c/src/lib/libbsp/i386/pc386/console/console_select.c
@@ -3,14 +3,14 @@
*
* @ingroup Console
*
- * @brief Generic libchip console select
+ * @brief pc397 console select
*
* This file contains a routine to select the console based upon a number
* of criteria.
*/
/*
- * COPYRIGHT (c) 2011-2012.
+ * COPYRIGHT (c) 2011-2012, 2016.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
@@ -77,52 +77,154 @@ static rtems_device_minor_number bsp_First_Available_Device( void )
rtems_fatal_error_occurred(RTEMS_IO_ERROR);
}
-void bsp_console_select(void)
+static bool bsp_find_console_entry(
+ const char *match,
+ size_t length,
+ rtems_device_minor_number *match_minor
+)
{
- static const char* opt;
+ 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 bool parse_printk_or_console(
+ const char *param,
+ rtems_device_minor_number *minor_out
+)
+{
+ static const char *opt;
+ char working[64] = "";
+ char *p;
/*
* Check the command line for the type of mode the console is.
*/
- opt = bsp_cmdline_arg ("--console=");
+ opt = bsp_cmdline_arg(param);
+ if ( !opt ) {
+ return false;
+ }
+
+ /*
+ * bsp_cmdline_arg() returns pointer to a string. It may not be the
+ * last string on the command line.
+ */
+ strncpy( working, opt, sizeof(working) );
+ p = strchr( working, ' ' );
+ if ( p ) {
+ *p = '\0';
+ }
- if (opt) {
- const char* comma;
+ const char *comma;
+ size_t length = NAME_MAX;
+ rtems_device_minor_number minor;
+ char *option = working;
- opt += sizeof ("--console=") - 1;
- if (strncmp (opt, "console", sizeof ("console") - 1) == 0) {
- Console_Port_Minor = BSP_CONSOLE_VGA;
- BSPPrintkPort = BSP_CONSOLE_VGA;
- } else if (strncmp (opt, "com1", sizeof ("com1") - 1) == 0) {
- Console_Port_Minor = BSP_CONSOLE_COM1;
- BSPPrintkPort = BSP_CONSOLE_COM1;
- } else if (strncmp (opt, "com2", sizeof ("com2") - 1) == 0) {
- Console_Port_Minor = BSP_CONSOLE_COM2;
- BSPPrintkPort = BSP_CONSOLE_COM2;
- }
+ /*
+ * Only match up to a comma or NULL
+ */
+ comma = strchr (option, ',');
- comma = strchr (opt, ',');
-
- if (comma) {
- console_tbl *conscfg;
-
- comma += 1;
- conscfg = &Console_Configuration_Ports[Console_Port_Minor];
- if (strncmp (opt, "115200", sizeof ("115200") - 1) == 0)
- conscfg->pDeviceParams = (void *)115200;
- else if (strncmp (opt, "57600", sizeof ("57600") - 1) == 0)
- conscfg->pDeviceParams = (void *)57600;
- else if (strncmp (opt, "38400", sizeof ("38400") - 1) == 0)
- conscfg->pDeviceParams = (void *)38400;
- else if (strncmp (opt, "19200", sizeof ("19200") - 1) == 0)
- conscfg->pDeviceParams = (void *)19200;
- else if (strncmp (opt, "9600", sizeof ("9600") - 1) == 0)
- conscfg->pDeviceParams = (void *)9600;
- else if (strncmp (opt, "4800", sizeof ("4800") - 1) == 0)
- conscfg->pDeviceParams = (void *)4800;
- }
+ if ( comma ) {
+ length = comma - option;
+ }
+
+ option += strnlen(param, 32);
+
+ if ( !bsp_find_console_entry( option, length, &minor ) ) {
+ return false;
+ }
+
+ *minor_out = minor;
+ if (comma) {
+ console_tbl *conscfg;
+
+ comma += 1;
+ conscfg = &Console_Configuration_Ports[minor];
+ if (strncmp (option, "115200", sizeof ("115200") - 1) == 0)
+ conscfg->pDeviceParams = (void *)115200;
+ else if (strncmp (option, "57600", sizeof ("57600") - 1) == 0)
+ conscfg->pDeviceParams = (void *)57600;
+ else if (strncmp (option, "38400", sizeof ("38400") - 1) == 0)
+ conscfg->pDeviceParams = (void *)38400;
+ else if (strncmp (option, "19200", sizeof ("19200") - 1) == 0)
+ conscfg->pDeviceParams = (void *)19200;
+ else if (strncmp (option, "9600", sizeof ("9600") - 1) == 0)
+ conscfg->pDeviceParams = (void *)9600;
+ else if (strncmp (option, "4800", sizeof ("4800") - 1) == 0)
+ conscfg->pDeviceParams = (void *)4800;
}
+ return true;
+}
+
+/*
+ * Helper to retrieve device name
+ */
+static inline const char *get_name(
+ rtems_device_minor_number minor
+)
+{
+ return Console_Port_Tbl[minor]->sDeviceName;
+}
+
+/*
+ * Parse the arguments early so the printk and console ports are
+ * set appropriately.
+ */
+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();
+
+ /*
+ * 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;
+ }
+
+ /*
+ * But if explicitly specified, attempt to honor it.
+ */
+ if ( parse_printk_or_console( "--printk=", &minor ) ) {
+ BSPPrintkPort = minor;
+ }
+
+#if 0
+ printk( "Console device: %s\n", get_name(Console_Port_Minor) );
+ printk( "printk device: %s\n", get_name(BSPPrintkPort) );
+#endif
+}
+
+/*
+ * This handles the selection of the console after the devices are
+ * initialized.
+ */
+void bsp_console_select(void)
+{
#ifdef RTEMS_RUNTIME_CONSOLE_SELECT
if ( BSP_runtime_console_select )
BSP_runtime_console_select(&BSPPrintkPort, &Console_Port_Minor);
@@ -145,7 +247,7 @@ void bsp_console_select(void)
if ( !bsp_Is_Available( Console_Port_Minor ) ) {
printk(
"Error finding %s setting console to first available\n",
- Console_Port_Tbl[Console_Port_Minor]->sDeviceName
+ get_name(Console_Port_Minor)
);
Console_Port_Minor = bsp_First_Available_Device();
}
diff --git a/c/src/lib/libbsp/i386/pc386/include/bsp.h b/c/src/lib/libbsp/i386/pc386/include/bsp.h
index 5778c75696..ed5c31947e 100644
--- a/c/src/lib/libbsp/i386/pc386/include/bsp.h
+++ b/c/src/lib/libbsp/i386/pc386/include/bsp.h
@@ -282,6 +282,12 @@ void C_dispatch_isr(int vector);
const pci_config_access_functions *pci_bios_initialize(void);
const pci_config_access_functions *pci_io_initialize(void);
+/*
+ * Helper to parse boot command line arguments related to the console driver
+ */
+void pc386_parse_console_arguments(void);
+
+
#ifdef __cplusplus
}
#endif
diff --git a/c/src/lib/libbsp/i386/pc386/startup/bspstart.c b/c/src/lib/libbsp/i386/pc386/startup/bspstart.c
index f74300e971..7cd859f686 100644
--- a/c/src/lib/libbsp/i386/pc386/startup/bspstart.c
+++ b/c/src/lib/libbsp/i386/pc386/startup/bspstart.c
@@ -107,6 +107,15 @@ static void bsp_start_default( void )
*/
bsp_pci_initialize_helper();
+ /*
+ * 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.
+ */
+ pc386_parse_console_arguments();
+
#if (BSP_IS_EDISON == 0)
Clock_driver_install_handler();
#endif
diff --git a/c/src/lib/libbsp/shared/console.c b/c/src/lib/libbsp/shared/console.c
index 9c739a3e52..81a70b1b6c 100644
--- a/c/src/lib/libbsp/shared/console.c
+++ b/c/src/lib/libbsp/shared/console.c
@@ -34,12 +34,12 @@ rtems_device_minor_number Console_Port_Minor = 0;
static bool console_initialized = false;
/*
- * console_initialize_pointers
+ * console_initialize_data
*
* This method is used to initialize the table of pointers to the
* serial port configuration structure entries.
*/
-static void console_initialize_pointers(void)
+void console_initialize_data(void)
{
int i;
@@ -69,7 +69,7 @@ void console_register_devices(
int old_number_of_ports;
int i;
- console_initialize_pointers();
+ console_initialize_data();
/*
* console_initialize has been invoked so it is now too late to
@@ -252,7 +252,7 @@ rtems_device_driver console_initialize(
* must still initialize pointers and set Console_Port_Data.
*/
if ( ! Console_Port_Tbl ) {
- console_initialize_pointers();
+ console_initialize_data();
Console_Port_Data = calloc( Console_Port_Count, sizeof( console_data ) );
if ( Console_Port_Data == NULL ) {
bsp_fatal( BSP_FATAL_CONSOLE_NO_MEMORY_3 );
diff --git a/c/src/lib/libbsp/shared/console_private.h b/c/src/lib/libbsp/shared/console_private.h
index 52dc421e14..ee89eb2051 100644
--- a/c/src/lib/libbsp/shared/console_private.h
+++ b/c/src/lib/libbsp/shared/console_private.h
@@ -7,7 +7,7 @@
*/
/*
- * COPYRIGHT (c) 1989-2011.
+ * COPYRIGHT (c) 1989-2011, 2016.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
@@ -58,6 +58,16 @@ extern int bsp_com_inch(void);
int vt_ioctl( unsigned int cmd, unsigned long arg);
/**
+ * @brief console_initialize_data
+ *
+ * This must be called before dynamic registration of devices can occur.
+ * It is normally called as a side-effect of @a console_initialize() but
+ * if a probe and dynamic registration occurs before that, then this method
+ * should be explicitly invoked.
+ */
+void console_initialize_data(void);
+
+/**
* @brief console_register_devices
*
* This function expands the console table to include previous