]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[serial] Check for UART existence in uart_select()
authorMichael Brown <mcb30@ipxe.org>
Fri, 31 Jul 2015 10:19:19 +0000 (11:19 +0100)
committerMichael Brown <mcb30@ipxe.org>
Fri, 31 Jul 2015 10:19:19 +0000 (11:19 +0100)
Check for existence of the UART in uart_select(), not just in
uart_init().  This allows uart_select() to refuse to set a non-working
address in uart->base, which in turns means that the serial console
code will not attempt to use a non-existent UART.

Reported-by: Torgeir Wulfsberg <Torgeir.Wulfsberg@kongsberg.com>
Reported-by: Ján ONDREJ (SAL) <ondrejj@salstar.sk>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/arch/x86/core/x86_uart.c
src/core/uart.c
src/include/ipxe/uart.h

index 7c3a01d6658ad7f2089a875e0c7142bcb4a673d3..e455775bfc20a3cf8239b38d9dfcef878ca8d995 100644 (file)
@@ -48,15 +48,22 @@ static uint16_t uart_base[] = {
  * @ret rc             Return status code
  */
 int uart_select ( struct uart *uart, unsigned int port ) {
-
-       /* Clear UART base */
-       uart->base = NULL;
+       int rc;
 
        /* Set new UART base */
-       if ( port < ( sizeof ( uart_base ) / sizeof ( uart_base[0] ) ) ) {
-               uart->base = ( ( void * ) ( intptr_t ) uart_base[port] );
-               return 0;
-       } else {
-               return -ENODEV;
+       if ( port >= ( sizeof ( uart_base ) / sizeof ( uart_base[0] ) ) ) {
+               rc = -ENODEV;
+               goto err;
        }
+       uart->base = ( ( void * ) ( intptr_t ) uart_base[port] );
+
+       /* Check that UART exists */
+       if ( ( rc = uart_exists ( uart ) ) != 0 )
+               goto err;
+
+       return 0;
+
+ err:
+       uart->base = NULL;
+       return rc;
 }
index 77721484ae14535d9b700dccf25afea6ef64e2c0..b85fe0767c1a792806cac38d5b157a28ddc0bd48 100644 (file)
@@ -80,20 +80,18 @@ void uart_flush ( struct uart *uart ) {
 }
 
 /**
- * Initialise UART
+ * Check for existence of UART
  *
  * @v uart             UART
- * @v baud             Baud rate, or zero to leave unchanged
- * @v lcr              Line control register value, or zero to leave unchanged
  * @ret rc             Return status code
  */
-int uart_init ( struct uart *uart, unsigned int baud, uint8_t lcr ) {
-       uint8_t dlm;
-       uint8_t dll;
+int uart_exists ( struct uart *uart ) {
 
-       /* Check for existence of UART */
+       /* Fail if no UART port is defined */
        if ( ! uart->base )
                return -ENODEV;
+
+       /* Fail if UART scratch register seems not to be present */
        uart_write ( uart, UART_SCR, 0x18 );
        if ( uart_read ( uart, UART_SCR ) != 0x18 )
                return -ENODEV;
@@ -101,6 +99,26 @@ int uart_init ( struct uart *uart, unsigned int baud, uint8_t lcr ) {
        if ( uart_read ( uart, UART_SCR ) != 0xae )
                return -ENODEV;
 
+       return 0;
+}
+
+/**
+ * Initialise UART
+ *
+ * @v uart             UART
+ * @v baud             Baud rate, or zero to leave unchanged
+ * @v lcr              Line control register value, or zero to leave unchanged
+ * @ret rc             Return status code
+ */
+int uart_init ( struct uart *uart, unsigned int baud, uint8_t lcr ) {
+       uint8_t dlm;
+       uint8_t dll;
+       int rc;
+
+       /* Check for existence of UART */
+       if ( ( rc = uart_exists ( uart ) ) != 0 )
+               return rc;
+
        /* Configure divisor and line control register, if applicable */
        if ( ! lcr )
                lcr = uart_read ( uart, UART_LCR );
index 122c79b135446ac608fa8518dda24a5901a52e62..c63eae61549ef072b64f33daf6e2f8e9d9a34427 100644 (file)
@@ -126,6 +126,7 @@ static inline uint8_t uart_receive ( struct uart *uart ) {
 
 extern void uart_transmit ( struct uart *uart, uint8_t data );
 extern void uart_flush ( struct uart *uart );
+extern int uart_exists ( struct uart *uart );
 extern int uart_init ( struct uart *uart, unsigned int baud, uint8_t lcr );
 
 #endif /* _IPXE_UART_H */