summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/arch/x86/core/x86_uart.c23
-rw-r--r--src/core/uart.c32
-rw-r--r--src/include/ipxe/uart.h1
3 files changed, 41 insertions, 15 deletions
diff --git a/src/arch/x86/core/x86_uart.c b/src/arch/x86/core/x86_uart.c
index 7c3a01d66..e455775bf 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 77721484a..b85fe0767 100644
--- a/src/core/uart.c
+++ b/src/core/uart.c
@@ -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 );
diff --git a/src/include/ipxe/uart.h b/src/include/ipxe/uart.h
index 122c79b13..c63eae615 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 */