source: rtems/c/src/lib/libbsp/i386/pc386/console/console_select.c @ c3c57b1

Last change on this file since c3c57b1 was c3c57b1, checked in by Joel Sherrill <joel@…>, on Mar 10, 2016 at 4:33:27 PM

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.

  • Property mode set to 100644
File size: 6.1 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup Console
5 *
6 * @brief pc397 console select
7 *
8 * This file contains a routine to select the console based upon a number
9 * of criteria.
10 */
11
12/*
13 *  COPYRIGHT (c) 2011-2012, 2016.
14 *  On-Line Applications Research Corporation (OAR).
15 *
16 *  The license and distribution terms for this file may be
17 *  found in the file LICENSE in this distribution or at
18 *  http://www.rtems.org/license/LICENSE.
19 */
20
21#include <bsp.h>
22#include <rtems/libio.h>
23#include <stdlib.h>
24#include <assert.h>
25#include <termios.h>
26
27#include <rtems/termiostypes.h>
28#include <libchip/serial.h>
29#include "../../../shared/console_private.h"
30#ifdef RTEMS_RUNTIME_CONSOLE_SELECT
31  #include <crt.h>
32#endif
33
34/*
35 * Method to return true if the device associated with the
36 * minor number probs available.
37 */
38static bool bsp_Is_Available( rtems_device_minor_number minor )
39{
40  console_tbl  *cptr = Console_Port_Tbl[minor];
41
42  /*
43   * First perform the configuration dependent probe, then the
44   * device dependent probe
45   */
46  if ((!cptr->deviceProbe || cptr->deviceProbe(minor)) &&
47       cptr->pDeviceFns->deviceProbe(minor)) {
48    return true;
49  }
50  return false;
51}
52
53/*
54 * Method to return the first available device.
55 */
56static rtems_device_minor_number bsp_First_Available_Device( void )
57{
58  rtems_device_minor_number minor;
59
60  for (minor=0; minor < Console_Port_Count ; minor++) {
61    console_tbl  *cptr = Console_Port_Tbl[minor];
62
63    /*
64     * First perform the configuration dependent probe, then the
65     * device dependent probe
66     */
67
68    if ((!cptr->deviceProbe || cptr->deviceProbe(minor)) &&
69         cptr->pDeviceFns->deviceProbe(minor)) {
70      return minor;
71    }
72  }
73
74  /*
75   *  Error No devices were found.  We will want to bail here.
76   */
77  rtems_fatal_error_occurred(RTEMS_IO_ERROR);
78}
79
80static bool bsp_find_console_entry(
81  const char                *match,
82  size_t                     length,
83  rtems_device_minor_number *match_minor
84)
85{
86  rtems_device_minor_number  minor;
87  const char                *name;
88
89  for (minor=0; minor < Console_Port_Count ; minor++) {
90    console_tbl  *cptr = Console_Port_Tbl[minor];
91
92    /*
93     * Console table entries include /dev/ prefix, device names passed
94     * in on command line do not.
95     */
96    name = cptr->sDeviceName  + sizeof("/dev");
97    if ( !strncmp( name, match, length ) ) {
98      *match_minor = minor;
99      return true;
100    }
101  }
102
103  return false;
104}
105
106static bool parse_printk_or_console(
107  const char                *param,
108  rtems_device_minor_number *minor_out
109)
110{
111  static const char *opt;
112  char               working[64] = "";
113  char              *p;
114
115  /*
116   * Check the command line for the type of mode the console is.
117   */
118  opt = bsp_cmdline_arg(param);
119  if ( !opt ) {
120    return false;
121  }
122
123  /*
124   * bsp_cmdline_arg() returns pointer to a string. It may not be the
125   * last string on the command line.
126   */
127  strncpy( working, opt, sizeof(working) );
128  p = strchr( working, ' ' );
129  if ( p ) {
130    *p = '\0';
131  }
132
133  const char                *comma;
134  size_t                     length = NAME_MAX;
135  rtems_device_minor_number  minor;
136  char                      *option = working;
137
138  /*
139   * Only match up to a comma or NULL
140   */
141  comma = strchr (option, ',');
142
143  if ( comma ) {
144    length = comma - option;
145  }
146
147  option += strnlen(param, 32);
148
149  if ( !bsp_find_console_entry( option, length, &minor ) ) {
150    return false;
151  }
152
153  *minor_out = minor;
154  if (comma) {
155    console_tbl *conscfg;
156
157    comma += 1;
158    conscfg = &Console_Configuration_Ports[minor];
159    if (strncmp (option, "115200", sizeof ("115200") - 1) == 0)
160      conscfg->pDeviceParams = (void *)115200;
161    else if (strncmp (option, "57600", sizeof ("57600") - 1) == 0)
162      conscfg->pDeviceParams = (void *)57600;
163    else if (strncmp (option, "38400", sizeof ("38400") - 1) == 0)
164      conscfg->pDeviceParams = (void *)38400;
165    else if (strncmp (option, "19200", sizeof ("19200") - 1) == 0)
166      conscfg->pDeviceParams = (void *)19200;
167    else if (strncmp (option, "9600", sizeof ("9600") - 1) == 0)
168      conscfg->pDeviceParams = (void *)9600;
169    else if (strncmp (option, "4800", sizeof ("4800") - 1) == 0)
170      conscfg->pDeviceParams = (void *)4800;
171  }
172
173  return true;
174}
175
176/*
177 * Helper to retrieve device name
178 */
179static inline const char *get_name(
180  rtems_device_minor_number  minor
181)
182{
183  return Console_Port_Tbl[minor]->sDeviceName;
184}
185
186/*
187 * Parse the arguments early so the printk and console ports are
188 * set appropriately.
189 */
190void pc386_parse_console_arguments(void)
191{
192  rtems_device_minor_number  minor;
193
194  /*
195   * The console device driver must have its data structures initialized
196   * before we can iterate the table of devices for names.
197   */
198  console_initialize_data();
199
200  /*
201   * Assume that if only --console is specified, that printk() should
202   * follow that selection by default.
203   */
204  if ( parse_printk_or_console( "--console=", &minor ) ) {
205    Console_Port_Minor = minor;
206    BSPPrintkPort = minor;
207  }
208
209  /*
210   * But if explicitly specified, attempt to honor it.
211   */
212  if ( parse_printk_or_console( "--printk=",  &minor ) ) {
213    BSPPrintkPort = minor;
214  }
215
216#if 0
217  printk( "Console device: %s\n", get_name(Console_Port_Minor) );
218  printk( "printk device:  %s\n", get_name(BSPPrintkPort) );
219#endif
220}
221
222/*
223 *  This handles the selection of the console after the devices are
224 *  initialized.
225 */
226void bsp_console_select(void)
227{
228  #ifdef RTEMS_RUNTIME_CONSOLE_SELECT
229    if ( BSP_runtime_console_select )
230      BSP_runtime_console_select(&BSPPrintkPort, &Console_Port_Minor);
231
232    /*
233     * If no video card, fall back to serial port console
234     */
235    if((Console_Port_Minor == BSP_CONSOLE_VGA)
236     && (*(unsigned char*) NB_MAX_ROW_ADDR == 0)
237     && (*(unsigned short*)NB_MAX_COL_ADDR == 0)) {
238      Console_Port_Minor = BSP_CONSOLE_COM2;
239      BSPPrintkPort      = BSP_CONSOLE_COM1;
240    }
241  #endif
242
243  /*
244   * If the device that was selected isn't available then
245   * let the user know and select the first available device.
246   */
247  if ( !bsp_Is_Available( Console_Port_Minor ) ) {
248    printk(
249      "Error finding %s setting console to first available\n",
250      get_name(Console_Port_Minor)
251    );
252    Console_Port_Minor = bsp_First_Available_Device();
253  }
254}
Note: See TracBrowser for help on using the repository browser.