[441b90e] | 1 | /** |
---|
| 2 | * @file |
---|
| 3 | * |
---|
| 4 | * @ingroup Console |
---|
| 5 | * |
---|
[c3c57b1] | 6 | * @brief pc397 console select |
---|
[52694844] | 7 | * |
---|
| 8 | * This file contains a routine to select the console based upon a number |
---|
| 9 | * of criteria. |
---|
[441b90e] | 10 | */ |
---|
| 11 | |
---|
| 12 | /* |
---|
[c3c57b1] | 13 | * COPYRIGHT (c) 2011-2012, 2016. |
---|
[441b90e] | 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 |
---|
[c499856] | 18 | * http://www.rtems.org/license/LICENSE. |
---|
[441b90e] | 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 | |
---|
[22bbb9f1] | 34 | /* |
---|
| 35 | * Forward prototype |
---|
| 36 | */ |
---|
| 37 | extern bool pc386_com1_com4_enabled(int); |
---|
| 38 | |
---|
| 39 | /* |
---|
| 40 | * This method is used to determine if COM1-COM4 are enabled based upon |
---|
| 41 | * boot command line arguments. |
---|
| 42 | */ |
---|
| 43 | static bool are_com1_com4_enabled; |
---|
| 44 | |
---|
| 45 | bool pc386_com1_com4_enabled(int minor) |
---|
| 46 | { |
---|
| 47 | return are_com1_com4_enabled; |
---|
| 48 | } |
---|
| 49 | |
---|
[441b90e] | 50 | /* |
---|
| 51 | * Method to return true if the device associated with the |
---|
| 52 | * minor number probs available. |
---|
| 53 | */ |
---|
| 54 | static bool bsp_Is_Available( rtems_device_minor_number minor ) |
---|
| 55 | { |
---|
| 56 | console_tbl *cptr = Console_Port_Tbl[minor]; |
---|
| 57 | |
---|
| 58 | /* |
---|
| 59 | * First perform the configuration dependent probe, then the |
---|
| 60 | * device dependent probe |
---|
| 61 | */ |
---|
| 62 | if ((!cptr->deviceProbe || cptr->deviceProbe(minor)) && |
---|
| 63 | cptr->pDeviceFns->deviceProbe(minor)) { |
---|
| 64 | return true; |
---|
| 65 | } |
---|
| 66 | return false; |
---|
| 67 | } |
---|
| 68 | |
---|
| 69 | /* |
---|
| 70 | * Method to return the first available device. |
---|
| 71 | */ |
---|
| 72 | static rtems_device_minor_number bsp_First_Available_Device( void ) |
---|
| 73 | { |
---|
| 74 | rtems_device_minor_number minor; |
---|
| 75 | |
---|
| 76 | for (minor=0; minor < Console_Port_Count ; minor++) { |
---|
| 77 | console_tbl *cptr = Console_Port_Tbl[minor]; |
---|
| 78 | |
---|
| 79 | /* |
---|
| 80 | * First perform the configuration dependent probe, then the |
---|
| 81 | * device dependent probe |
---|
| 82 | */ |
---|
| 83 | |
---|
| 84 | if ((!cptr->deviceProbe || cptr->deviceProbe(minor)) && |
---|
| 85 | cptr->pDeviceFns->deviceProbe(minor)) { |
---|
| 86 | return minor; |
---|
| 87 | } |
---|
| 88 | } |
---|
| 89 | |
---|
| 90 | /* |
---|
| 91 | * Error No devices were found. We will want to bail here. |
---|
| 92 | */ |
---|
| 93 | rtems_fatal_error_occurred(RTEMS_IO_ERROR); |
---|
| 94 | } |
---|
| 95 | |
---|
[c3c57b1] | 96 | static bool bsp_find_console_entry( |
---|
| 97 | const char *match, |
---|
| 98 | size_t length, |
---|
| 99 | rtems_device_minor_number *match_minor |
---|
| 100 | ) |
---|
[441b90e] | 101 | { |
---|
[c3c57b1] | 102 | rtems_device_minor_number minor; |
---|
| 103 | const char *name; |
---|
| 104 | |
---|
| 105 | for (minor=0; minor < Console_Port_Count ; minor++) { |
---|
| 106 | console_tbl *cptr = Console_Port_Tbl[minor]; |
---|
| 107 | |
---|
| 108 | /* |
---|
| 109 | * Console table entries include /dev/ prefix, device names passed |
---|
| 110 | * in on command line do not. |
---|
| 111 | */ |
---|
| 112 | name = cptr->sDeviceName + sizeof("/dev"); |
---|
| 113 | if ( !strncmp( name, match, length ) ) { |
---|
| 114 | *match_minor = minor; |
---|
| 115 | return true; |
---|
| 116 | } |
---|
| 117 | } |
---|
| 118 | |
---|
| 119 | return false; |
---|
| 120 | } |
---|
| 121 | |
---|
[22bbb9f1] | 122 | static void parse_com1_com4_enable(void) |
---|
| 123 | { |
---|
| 124 | static const char *opt; |
---|
| 125 | |
---|
| 126 | /* |
---|
| 127 | * Check the command line to see if com1-com4 are disabled. |
---|
| 128 | */ |
---|
| 129 | opt = bsp_cmdline_arg("--disable-com1-com4"); |
---|
| 130 | if ( opt ) { |
---|
| 131 | printk( "Disable COM1-COM4 per boot argument\n" ); |
---|
| 132 | are_com1_com4_enabled = false; |
---|
| 133 | } else { |
---|
| 134 | are_com1_com4_enabled = true; |
---|
| 135 | } |
---|
| 136 | } |
---|
| 137 | |
---|
[c3c57b1] | 138 | static bool parse_printk_or_console( |
---|
| 139 | const char *param, |
---|
| 140 | rtems_device_minor_number *minor_out |
---|
| 141 | ) |
---|
| 142 | { |
---|
| 143 | static const char *opt; |
---|
| 144 | char working[64] = ""; |
---|
| 145 | char *p; |
---|
[441b90e] | 146 | |
---|
| 147 | /* |
---|
| 148 | * Check the command line for the type of mode the console is. |
---|
| 149 | */ |
---|
[c3c57b1] | 150 | opt = bsp_cmdline_arg(param); |
---|
| 151 | if ( !opt ) { |
---|
| 152 | return false; |
---|
| 153 | } |
---|
| 154 | |
---|
| 155 | /* |
---|
| 156 | * bsp_cmdline_arg() returns pointer to a string. It may not be the |
---|
| 157 | * last string on the command line. |
---|
| 158 | */ |
---|
| 159 | strncpy( working, opt, sizeof(working) ); |
---|
| 160 | p = strchr( working, ' ' ); |
---|
| 161 | if ( p ) { |
---|
| 162 | *p = '\0'; |
---|
| 163 | } |
---|
[441b90e] | 164 | |
---|
[c3c57b1] | 165 | const char *comma; |
---|
| 166 | size_t length = NAME_MAX; |
---|
| 167 | rtems_device_minor_number minor; |
---|
| 168 | char *option = working; |
---|
[441b90e] | 169 | |
---|
[c3c57b1] | 170 | /* |
---|
| 171 | * Only match up to a comma or NULL |
---|
| 172 | */ |
---|
| 173 | comma = strchr (option, ','); |
---|
[441b90e] | 174 | |
---|
[c3c57b1] | 175 | if ( comma ) { |
---|
| 176 | length = comma - option; |
---|
| 177 | } |
---|
| 178 | |
---|
| 179 | option += strnlen(param, 32); |
---|
| 180 | |
---|
| 181 | if ( !bsp_find_console_entry( option, length, &minor ) ) { |
---|
| 182 | return false; |
---|
| 183 | } |
---|
| 184 | |
---|
| 185 | *minor_out = minor; |
---|
| 186 | if (comma) { |
---|
| 187 | console_tbl *conscfg; |
---|
| 188 | |
---|
| 189 | comma += 1; |
---|
| 190 | conscfg = &Console_Configuration_Ports[minor]; |
---|
| 191 | if (strncmp (option, "115200", sizeof ("115200") - 1) == 0) |
---|
| 192 | conscfg->pDeviceParams = (void *)115200; |
---|
| 193 | else if (strncmp (option, "57600", sizeof ("57600") - 1) == 0) |
---|
| 194 | conscfg->pDeviceParams = (void *)57600; |
---|
| 195 | else if (strncmp (option, "38400", sizeof ("38400") - 1) == 0) |
---|
| 196 | conscfg->pDeviceParams = (void *)38400; |
---|
| 197 | else if (strncmp (option, "19200", sizeof ("19200") - 1) == 0) |
---|
| 198 | conscfg->pDeviceParams = (void *)19200; |
---|
| 199 | else if (strncmp (option, "9600", sizeof ("9600") - 1) == 0) |
---|
| 200 | conscfg->pDeviceParams = (void *)9600; |
---|
| 201 | else if (strncmp (option, "4800", sizeof ("4800") - 1) == 0) |
---|
| 202 | conscfg->pDeviceParams = (void *)4800; |
---|
[441b90e] | 203 | } |
---|
| 204 | |
---|
[c3c57b1] | 205 | return true; |
---|
| 206 | } |
---|
| 207 | |
---|
| 208 | /* |
---|
| 209 | * Helper to retrieve device name |
---|
| 210 | */ |
---|
| 211 | static inline const char *get_name( |
---|
| 212 | rtems_device_minor_number minor |
---|
| 213 | ) |
---|
| 214 | { |
---|
| 215 | return Console_Port_Tbl[minor]->sDeviceName; |
---|
| 216 | } |
---|
| 217 | |
---|
| 218 | /* |
---|
| 219 | * Parse the arguments early so the printk and console ports are |
---|
| 220 | * set appropriately. |
---|
| 221 | */ |
---|
| 222 | void pc386_parse_console_arguments(void) |
---|
| 223 | { |
---|
| 224 | rtems_device_minor_number minor; |
---|
| 225 | |
---|
| 226 | /* |
---|
| 227 | * The console device driver must have its data structures initialized |
---|
| 228 | * before we can iterate the table of devices for names. |
---|
| 229 | */ |
---|
| 230 | console_initialize_data(); |
---|
| 231 | |
---|
[22bbb9f1] | 232 | /* |
---|
| 233 | * Determine if COM1-COM4 were disabled. |
---|
| 234 | */ |
---|
| 235 | parse_com1_com4_enable(); |
---|
| 236 | |
---|
[c3c57b1] | 237 | /* |
---|
| 238 | * Assume that if only --console is specified, that printk() should |
---|
| 239 | * follow that selection by default. |
---|
| 240 | */ |
---|
| 241 | if ( parse_printk_or_console( "--console=", &minor ) ) { |
---|
| 242 | Console_Port_Minor = minor; |
---|
| 243 | BSPPrintkPort = minor; |
---|
| 244 | } |
---|
| 245 | |
---|
| 246 | /* |
---|
| 247 | * But if explicitly specified, attempt to honor it. |
---|
| 248 | */ |
---|
| 249 | if ( parse_printk_or_console( "--printk=", &minor ) ) { |
---|
| 250 | BSPPrintkPort = minor; |
---|
| 251 | } |
---|
| 252 | |
---|
| 253 | #if 0 |
---|
| 254 | printk( "Console device: %s\n", get_name(Console_Port_Minor) ); |
---|
| 255 | printk( "printk device: %s\n", get_name(BSPPrintkPort) ); |
---|
| 256 | #endif |
---|
| 257 | } |
---|
| 258 | |
---|
| 259 | /* |
---|
| 260 | * This handles the selection of the console after the devices are |
---|
| 261 | * initialized. |
---|
| 262 | */ |
---|
| 263 | void bsp_console_select(void) |
---|
| 264 | { |
---|
[441b90e] | 265 | #ifdef RTEMS_RUNTIME_CONSOLE_SELECT |
---|
| 266 | if ( BSP_runtime_console_select ) |
---|
| 267 | BSP_runtime_console_select(&BSPPrintkPort, &Console_Port_Minor); |
---|
| 268 | |
---|
| 269 | /* |
---|
| 270 | * If no video card, fall back to serial port console |
---|
| 271 | */ |
---|
| 272 | if((Console_Port_Minor == BSP_CONSOLE_VGA) |
---|
| 273 | && (*(unsigned char*) NB_MAX_ROW_ADDR == 0) |
---|
| 274 | && (*(unsigned short*)NB_MAX_COL_ADDR == 0)) { |
---|
| 275 | Console_Port_Minor = BSP_CONSOLE_COM2; |
---|
| 276 | BSPPrintkPort = BSP_CONSOLE_COM1; |
---|
| 277 | } |
---|
| 278 | #endif |
---|
| 279 | |
---|
| 280 | /* |
---|
| 281 | * If the device that was selected isn't available then |
---|
| 282 | * let the user know and select the first available device. |
---|
| 283 | */ |
---|
| 284 | if ( !bsp_Is_Available( Console_Port_Minor ) ) { |
---|
| 285 | printk( |
---|
| 286 | "Error finding %s setting console to first available\n", |
---|
[c3c57b1] | 287 | get_name(Console_Port_Minor) |
---|
[441b90e] | 288 | ); |
---|
| 289 | Console_Port_Minor = bsp_First_Available_Device(); |
---|
| 290 | } |
---|
| 291 | } |
---|