diff --git a/src/arch/x86/core/x86_uart.c b/src/arch/x86/core/x86_uart.c index 7c3a01d6..e455775b 100644 --- a/src/arch/x86/core/x86_uart.c +++ b/src/arch/x86/core/x86_uart.c @@ -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; } diff --git a/src/core/uart.c b/src/core/uart.c index 77721484..b85fe076 100644 --- a/src/core/uart.c +++ b/src/core/uart.c @@ -79,6 +79,29 @@ void uart_flush ( struct uart *uart ) { } } +/** + * Check for existence of UART + * + * @v uart UART + * @ret rc Return status code + */ +int uart_exists ( struct uart *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; + uart_write ( uart, UART_SCR, 0xae ); + if ( uart_read ( uart, UART_SCR ) != 0xae ) + return -ENODEV; + + return 0; +} + /** * Initialise UART * @@ -90,16 +113,11 @@ void uart_flush ( struct uart *uart ) { 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 ( ! uart->base ) - return -ENODEV; - uart_write ( uart, UART_SCR, 0x18 ); - if ( uart_read ( uart, UART_SCR ) != 0x18 ) - return -ENODEV; - uart_write ( uart, UART_SCR, 0xae ); - if ( uart_read ( uart, UART_SCR ) != 0xae ) - return -ENODEV; + if ( ( rc = uart_exists ( uart ) ) != 0 ) + return rc; /* Configure divisor and line control register, if applicable */ if ( ! lcr ) diff --git a/src/include/ipxe/uart.h b/src/include/ipxe/uart.h index 122c79b1..c63eae61 100644 --- a/src/include/ipxe/uart.h +++ b/src/include/ipxe/uart.h @@ -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 */