mirror of https://github.com/ipxe/ipxe.git
[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>pull/39/head
parent
9aa55f811a
commit
2849932c48
|
@ -48,15 +48,22 @@ static uint16_t uart_base[] = {
|
||||||
* @ret rc Return status code
|
* @ret rc Return status code
|
||||||
*/
|
*/
|
||||||
int uart_select ( struct uart *uart, unsigned int port ) {
|
int uart_select ( struct uart *uart, unsigned int port ) {
|
||||||
|
int rc;
|
||||||
/* Clear UART base */
|
|
||||||
uart->base = NULL;
|
|
||||||
|
|
||||||
/* Set new UART base */
|
/* Set new UART base */
|
||||||
if ( port < ( sizeof ( uart_base ) / sizeof ( uart_base[0] ) ) ) {
|
if ( port >= ( sizeof ( uart_base ) / sizeof ( uart_base[0] ) ) ) {
|
||||||
uart->base = ( ( void * ) ( intptr_t ) uart_base[port] );
|
rc = -ENODEV;
|
||||||
return 0;
|
goto err;
|
||||||
} else {
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
}
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
* Initialise UART
|
||||||
*
|
*
|
||||||
|
@ -90,16 +113,11 @@ void uart_flush ( struct uart *uart ) {
|
||||||
int uart_init ( struct uart *uart, unsigned int baud, uint8_t lcr ) {
|
int uart_init ( struct uart *uart, unsigned int baud, uint8_t lcr ) {
|
||||||
uint8_t dlm;
|
uint8_t dlm;
|
||||||
uint8_t dll;
|
uint8_t dll;
|
||||||
|
int rc;
|
||||||
|
|
||||||
/* Check for existence of UART */
|
/* Check for existence of UART */
|
||||||
if ( ! uart->base )
|
if ( ( rc = uart_exists ( uart ) ) != 0 )
|
||||||
return -ENODEV;
|
return rc;
|
||||||
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;
|
|
||||||
|
|
||||||
/* Configure divisor and line control register, if applicable */
|
/* Configure divisor and line control register, if applicable */
|
||||||
if ( ! lcr )
|
if ( ! lcr )
|
||||||
|
|
|
@ -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_transmit ( struct uart *uart, uint8_t data );
|
||||||
extern void uart_flush ( struct uart *uart );
|
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 );
|
extern int uart_init ( struct uart *uart, unsigned int baud, uint8_t lcr );
|
||||||
|
|
||||||
#endif /* _IPXE_UART_H */
|
#endif /* _IPXE_UART_H */
|
||||||
|
|
Loading…
Reference in New Issue