[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 | |
---|
| 34 | /* |
---|
| 35 | * Method to return true if the device associated with the |
---|
| 36 | * minor number probs available. |
---|
| 37 | */ |
---|
| 38 | static 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 | */ |
---|
| 56 | static 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 | |
---|
[c3c57b1] | 80 | static bool bsp_find_console_entry( |
---|
| 81 | const char *match, |
---|
| 82 | size_t length, |
---|
| 83 | rtems_device_minor_number *match_minor |
---|
| 84 | ) |
---|
[441b90e] | 85 | { |
---|
[c3c57b1] | 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 | |
---|
| 106 | static 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; |
---|
[441b90e] | 114 | |
---|
| 115 | /* |
---|
| 116 | * Check the command line for the type of mode the console is. |
---|
| 117 | */ |
---|
[c3c57b1] | 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 | } |
---|
[441b90e] | 132 | |
---|
[c3c57b1] | 133 | const char *comma; |
---|
| 134 | size_t length = NAME_MAX; |
---|
| 135 | rtems_device_minor_number minor; |
---|
| 136 | char *option = working; |
---|
[441b90e] | 137 | |
---|
[c3c57b1] | 138 | /* |
---|
| 139 | * Only match up to a comma or NULL |
---|
| 140 | */ |
---|
| 141 | comma = strchr (option, ','); |
---|
[441b90e] | 142 | |
---|
[c3c57b1] | 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; |
---|
[441b90e] | 171 | } |
---|
| 172 | |
---|
[c3c57b1] | 173 | return true; |
---|
| 174 | } |
---|
| 175 | |
---|
| 176 | /* |
---|
| 177 | * Helper to retrieve device name |
---|
| 178 | */ |
---|
| 179 | static 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 | */ |
---|
| 190 | void 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 | */ |
---|
| 226 | void bsp_console_select(void) |
---|
| 227 | { |
---|
[441b90e] | 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", |
---|
[c3c57b1] | 250 | get_name(Console_Port_Minor) |
---|
[441b90e] | 251 | ); |
---|
| 252 | Console_Port_Minor = bsp_First_Available_Device(); |
---|
| 253 | } |
---|
| 254 | } |
---|