Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:40

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup Console
0007  *
0008  * @brief pc386 console select
0009  *
0010  * This file contains a routine to select the console based upon a number
0011  * of criteria.
0012  */
0013 
0014 /*
0015  *  COPYRIGHT (c) 2011-2012, 2016.
0016  *  On-Line Applications Research Corporation (OAR).
0017  *
0018  * Redistribution and use in source and binary forms, with or without
0019  * modification, are permitted provided that the following conditions
0020  * are met:
0021  * 1. Redistributions of source code must retain the above copyright
0022  *    notice, this list of conditions and the following disclaimer.
0023  * 2. Redistributions in binary form must reproduce the above copyright
0024  *    notice, this list of conditions and the following disclaimer in the
0025  *    documentation and/or other materials provided with the distribution.
0026  *
0027  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0028  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0029  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0030  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0031  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0032  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0033  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0034  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0035  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0036  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0037  * POSSIBILITY OF SUCH DAMAGE.
0038  */
0039 
0040 #include <limits.h>
0041 #include <stdlib.h>
0042 #include <termios.h>
0043 
0044 #include <bsp.h>
0045 #include <libchip/serial.h>
0046 #include <rtems/libio.h>
0047 #include <rtems/console.h>
0048 #include <rtems/termiostypes.h>
0049 #include <bsp/bspimpl.h>
0050 
0051 #include "../../shared/dev/serial/legacy-console.h"
0052 #ifdef RTEMS_RUNTIME_CONSOLE_SELECT
0053   #include <crt.h>
0054 #endif
0055 
0056 /*
0057  * Method to return true if the device associated with the
0058  * minor number probs available.
0059  */
0060 static bool bsp_Is_Available( rtems_device_minor_number minor )
0061 {
0062   console_tbl  *cptr = Console_Port_Tbl[minor];
0063 
0064   /*
0065    * First perform the configuration dependent probe, then the
0066    * device dependent probe
0067    */
0068   if ((!cptr->deviceProbe || cptr->deviceProbe(minor)) &&
0069        cptr->pDeviceFns->deviceProbe(minor)) {
0070     return true;
0071   }
0072   return false;
0073 }
0074 
0075 /*
0076  * Method to return the first available device.
0077  */
0078 static rtems_device_minor_number bsp_First_Available_Device( void )
0079 {
0080   rtems_device_minor_number minor;
0081 
0082   for (minor=0; minor < Console_Port_Count ; minor++) {
0083     console_tbl  *cptr = Console_Port_Tbl[minor];
0084 
0085     /*
0086      * First perform the configuration dependent probe, then the
0087      * device dependent probe
0088      */
0089 
0090     if ((!cptr->deviceProbe || cptr->deviceProbe(minor)) &&
0091          cptr->pDeviceFns->deviceProbe(minor)) {
0092       return minor;
0093     }
0094   }
0095 
0096   /*
0097    *  Error No devices were found.  We will want to bail here.
0098    */
0099   rtems_fatal_error_occurred(RTEMS_IO_ERROR);
0100 }
0101 
0102 static bool parse_printk_or_console(
0103   const char                *param,
0104   rtems_device_minor_number *minor_out
0105 )
0106 {
0107   static const char         *opt;
0108   const char                *option;
0109   const char                *comma;
0110   size_t                     length;
0111   size_t                     index;
0112   rtems_device_minor_number  minor;
0113   console_tbl               *conscfg;
0114 
0115   /*
0116    * Check the command line for the type of mode the console is.
0117    */
0118   opt = bsp_cmdline_arg(param);
0119   if ( !opt ) {
0120     return false;
0121   }
0122 
0123   /*
0124    * Fine the length, there can be more command line visible.
0125    */
0126   length = 0;
0127   while ((opt[length] != ' ') && (opt[length] != '\0')) {
0128     ++length;
0129     if (length > NAME_MAX) {
0130       printk("invalid option (%s): too long\n", param);
0131       return false;
0132     }
0133   }
0134 
0135   /*
0136    * Only match up to a comma or NULL
0137    */
0138   index = 0;
0139   while ((opt[index] != '=') && (index < length)) {
0140     ++index;
0141   }
0142 
0143   if (opt[index] != '=') {
0144     printk("invalid option (%s): no equals\n", param);
0145     return false;
0146   }
0147 
0148   ++index;
0149   option = &opt[index];
0150 
0151   while ((opt[index] != ',') && (index < length)) {
0152     ++index;
0153   }
0154 
0155   if (opt[index] == ',')
0156     comma = &opt[index];
0157   else
0158     comma = NULL;
0159 
0160   length = &opt[index] - option;
0161 
0162   conscfg = console_find_console_entry( option, length, &minor );
0163   if ( conscfg == NULL ) {
0164     return false;
0165   }
0166 
0167   *minor_out = minor;
0168   if (comma) {
0169     option = comma + 1;
0170     if (strncmp (option, "115200", sizeof ("115200") - 1) == 0)
0171       conscfg->pDeviceParams = (void *)115200;
0172     else if (strncmp (option, "57600", sizeof ("57600") - 1) == 0)
0173       conscfg->pDeviceParams = (void *)57600;
0174     else if (strncmp (option, "38400", sizeof ("38400") - 1) == 0)
0175       conscfg->pDeviceParams = (void *)38400;
0176     else if (strncmp (option, "19200", sizeof ("19200") - 1) == 0)
0177       conscfg->pDeviceParams = (void *)19200;
0178     else if (strncmp (option, "9600", sizeof ("9600") - 1) == 0)
0179       conscfg->pDeviceParams = (void *)9600;
0180     else if (strncmp (option, "4800", sizeof ("4800") - 1) == 0)
0181       conscfg->pDeviceParams = (void *)4800;
0182   }
0183 
0184   return true;
0185 }
0186 
0187 /*
0188  * Helper to retrieve device name
0189  */
0190 static inline const char *get_name(
0191   rtems_device_minor_number  minor
0192 )
0193 {
0194   return Console_Port_Tbl[minor]->sDeviceName;
0195 }
0196 
0197 /*
0198  * Parse the arguments early so the printk and console ports are
0199  * set appropriately.
0200  */
0201 void pc386_parse_console_arguments(void)
0202 {
0203   rtems_device_minor_number minor;
0204   rtems_device_minor_number minor_console = 0;
0205   rtems_device_minor_number minor_printk = 0;
0206 
0207   /*
0208    * Assume that if only --console is specified, that printk() should
0209    * follow that selection by default.
0210    */
0211   if ( parse_printk_or_console( "--console=", &minor ) ) {
0212     minor_console = minor;
0213     minor_printk = minor;
0214   }
0215 
0216   /*
0217    * But if explicitly specified, attempt to honor it.
0218    */
0219   if ( parse_printk_or_console( "--printk=",  &minor ) ) {
0220     minor_printk = minor;
0221   }
0222 
0223   printk( "Console: %s printk: %s\n",
0224           get_name(minor_console),get_name(minor_printk) );
0225 
0226   /*
0227    * Any output after this can cause problems until termios is initialised.
0228    */
0229   Console_Port_Minor = minor_console;
0230   BSPPrintkPort = minor_printk;
0231 }
0232 
0233 /*
0234  *  This handles the selection of the console after the devices are
0235  *  initialized.
0236  */
0237 void bsp_console_select(void)
0238 {
0239   #ifdef RTEMS_RUNTIME_CONSOLE_SELECT
0240     /*
0241      * WARNING: This code is really needed any more and should be removed.
0242      *          references to COM1 and COM2 like they are wrong.
0243      */
0244     if ( BSP_runtime_console_select )
0245       BSP_runtime_console_select(&BSPPrintkPort, &Console_Port_Minor);
0246 
0247     /*
0248      * If no video card, fall back to serial port console
0249      */
0250     if((Console_Port_Minor == BSP_CONSOLE_VGA)
0251      && (*(unsigned char*) NB_MAX_ROW_ADDR == 0)
0252      && (*(unsigned short*)NB_MAX_COL_ADDR == 0)) {
0253       Console_Port_Minor = BSP_CONSOLE_COM2;
0254       BSPPrintkPort      = BSP_CONSOLE_COM1;
0255     }
0256   #endif
0257 
0258   /*
0259    * If the device that was selected isn't available then
0260    * let the user know and select the first available device.
0261    */
0262   if ( !bsp_Is_Available( Console_Port_Minor ) ) {
0263     printk(
0264       "Error finding %s setting console to first available\n",
0265       get_name(Console_Port_Minor)
0266     );
0267     Console_Port_Minor = bsp_First_Available_Device();
0268   }
0269 }