Browse Source

[serial] Check for UART existence in uart_select()

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>
tags/v1.20.1
Michael Brown 8 years ago
parent
commit
2849932c48
3 changed files with 41 additions and 15 deletions
  1. 15
    8
      src/arch/x86/core/x86_uart.c
  2. 25
    7
      src/core/uart.c
  3. 1
    0
      src/include/ipxe/uart.h

+ 15
- 8
src/arch/x86/core/x86_uart.c View File

@@ -48,15 +48,22 @@ static uint16_t uart_base[] = {
48 48
  * @ret rc		Return status code
49 49
  */
50 50
 int uart_select ( struct uart *uart, unsigned int port ) {
51
-
52
-	/* Clear UART base */
53
-	uart->base = NULL;
51
+	int rc;
54 52
 
55 53
 	/* Set new UART base */
56
-	if ( port < ( sizeof ( uart_base ) / sizeof ( uart_base[0] ) ) ) {
57
-		uart->base = ( ( void * ) ( intptr_t ) uart_base[port] );
58
-		return 0;
59
-	} else {
60
-		return -ENODEV;
54
+	if ( port >= ( sizeof ( uart_base ) / sizeof ( uart_base[0] ) ) ) {
55
+		rc = -ENODEV;
56
+		goto err;
61 57
 	}
58
+	uart->base = ( ( void * ) ( intptr_t ) uart_base[port] );
59
+
60
+	/* Check that UART exists */
61
+	if ( ( rc = uart_exists ( uart ) ) != 0 )
62
+		goto err;
63
+
64
+	return 0;
65
+
66
+ err:
67
+	uart->base = NULL;
68
+	return rc;
62 69
 }

+ 25
- 7
src/core/uart.c View File

@@ -80,20 +80,18 @@ void uart_flush ( struct uart *uart ) {
80 80
 }
81 81
 
82 82
 /**
83
- * Initialise UART
83
+ * Check for existence of UART
84 84
  *
85 85
  * @v uart		UART
86
- * @v baud		Baud rate, or zero to leave unchanged
87
- * @v lcr		Line control register value, or zero to leave unchanged
88 86
  * @ret rc		Return status code
89 87
  */
90
-int uart_init ( struct uart *uart, unsigned int baud, uint8_t lcr ) {
91
-	uint8_t dlm;
92
-	uint8_t dll;
88
+int uart_exists ( struct uart *uart ) {
93 89
 
94
-	/* Check for existence of UART */
90
+	/* Fail if no UART port is defined */
95 91
 	if ( ! uart->base )
96 92
 		return -ENODEV;
93
+
94
+	/* Fail if UART scratch register seems not to be present */
97 95
 	uart_write ( uart, UART_SCR, 0x18 );
98 96
 	if ( uart_read ( uart, UART_SCR ) != 0x18 )
99 97
 		return -ENODEV;
@@ -101,6 +99,26 @@ int uart_init ( struct uart *uart, unsigned int baud, uint8_t lcr ) {
101 99
 	if ( uart_read ( uart, UART_SCR ) != 0xae )
102 100
 		return -ENODEV;
103 101
 
102
+	return 0;
103
+}
104
+
105
+/**
106
+ * Initialise UART
107
+ *
108
+ * @v uart		UART
109
+ * @v baud		Baud rate, or zero to leave unchanged
110
+ * @v lcr		Line control register value, or zero to leave unchanged
111
+ * @ret rc		Return status code
112
+ */
113
+int uart_init ( struct uart *uart, unsigned int baud, uint8_t lcr ) {
114
+	uint8_t dlm;
115
+	uint8_t dll;
116
+	int rc;
117
+
118
+	/* Check for existence of UART */
119
+	if ( ( rc = uart_exists ( uart ) ) != 0 )
120
+		return rc;
121
+
104 122
 	/* Configure divisor and line control register, if applicable */
105 123
 	if ( ! lcr )
106 124
 		lcr = uart_read ( uart, UART_LCR );

+ 1
- 0
src/include/ipxe/uart.h View File

@@ -126,6 +126,7 @@ static inline uint8_t uart_receive ( struct uart *uart ) {
126 126
 
127 127
 extern void uart_transmit ( struct uart *uart, uint8_t data );
128 128
 extern void uart_flush ( struct uart *uart );
129
+extern int uart_exists ( struct uart *uart );
129 130
 extern int uart_init ( struct uart *uart, unsigned int baud, uint8_t lcr );
130 131
 
131 132
 #endif /* _IPXE_UART_H */

Loading…
Cancel
Save