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 9 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
  * @ret rc		Return status code
48
  * @ret rc		Return status code
49
  */
49
  */
50
 int uart_select ( struct uart *uart, unsigned int port ) {
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
 	/* Set new UART base */
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
 }
80
 }
81
 
81
 
82
 /**
82
 /**
83
- * Initialise UART
83
+ * Check for existence of UART
84
  *
84
  *
85
  * @v uart		UART
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
  * @ret rc		Return status code
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
 	if ( ! uart->base )
91
 	if ( ! uart->base )
96
 		return -ENODEV;
92
 		return -ENODEV;
93
+
94
+	/* Fail if UART scratch register seems not to be present */
97
 	uart_write ( uart, UART_SCR, 0x18 );
95
 	uart_write ( uart, UART_SCR, 0x18 );
98
 	if ( uart_read ( uart, UART_SCR ) != 0x18 )
96
 	if ( uart_read ( uart, UART_SCR ) != 0x18 )
99
 		return -ENODEV;
97
 		return -ENODEV;
101
 	if ( uart_read ( uart, UART_SCR ) != 0xae )
99
 	if ( uart_read ( uart, UART_SCR ) != 0xae )
102
 		return -ENODEV;
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
 	/* Configure divisor and line control register, if applicable */
122
 	/* Configure divisor and line control register, if applicable */
105
 	if ( ! lcr )
123
 	if ( ! lcr )
106
 		lcr = uart_read ( uart, UART_LCR );
124
 		lcr = uart_read ( uart, UART_LCR );

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

126
 
126
 
127
 extern void uart_transmit ( struct uart *uart, uint8_t data );
127
 extern void uart_transmit ( struct uart *uart, uint8_t data );
128
 extern void uart_flush ( struct uart *uart );
128
 extern void uart_flush ( struct uart *uart );
129
+extern int uart_exists ( struct uart *uart );
129
 extern int uart_init ( struct uart *uart, unsigned int baud, uint8_t lcr );
130
 extern int uart_init ( struct uart *uart, unsigned int baud, uint8_t lcr );
130
 
131
 
131
 #endif /* _IPXE_UART_H */
132
 #endif /* _IPXE_UART_H */

Loading…
Cancel
Save