[PATCH 06/17] pc386: Improve boot command arguments for console/printk device selection

Joel Sherrill joel at rtems.org
Wed Mar 9 22:24:51 UTC 2016


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.
This will allow dynamically discovered and registers devices on the
PCI bus to be selected as the console.
---
 .../lib/libbsp/i386/pc386/console/console_select.c | 180 ++++++++++++++++-----
 c/src/lib/libbsp/i386/pc386/include/bsp.h          |   6 +
 c/src/lib/libbsp/i386/pc386/startup/bspstart.c     |  10 +-
 c/src/lib/libbsp/shared/console.c                  |   8 +-
 c/src/lib/libbsp/shared/console_private.h          |  12 +-
 5 files changed, 171 insertions(+), 45 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 3a756b4..c78b4b8 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 3d29e3e..21591f6 100644
--- a/c/src/lib/libbsp/i386/pc386/include/bsp.h
+++ b/c/src/lib/libbsp/i386/pc386/include/bsp.h
@@ -275,6 +275,12 @@ uint32_t BSP_irq_count_dump(FILE *f);
 void raw_idt_notify(void);
 void C_dispatch_isr(int vector);
 
+/*
+ * 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 a0bbf66..26533ae 100644
--- a/c/src/lib/libbsp/i386/pc386/startup/bspstart.c
+++ b/c/src/lib/libbsp/i386/pc386/startup/bspstart.c
@@ -88,7 +88,6 @@ static void bsp_start_default( void )
   *edison_wd = 0x11f8;
 #endif
 
-
   /*
    * Calibrate variable for 1ms-loop (see timer.c)
    */
@@ -111,6 +110,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 9c739a3..81a70b1 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 52dc421..ee89eb2 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
-- 
1.8.3.1




More information about the devel mailing list