iPXE
serial.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 
26 /** @file
27  *
28  * Serial console
29  *
30  */
31 
32 #include <stddef.h>
33 #include <string.h>
34 #include <ipxe/init.h>
35 #include <ipxe/uart.h>
36 #include <ipxe/console.h>
37 #include <ipxe/serial.h>
38 #include <config/console.h>
39 #include <config/serial.h>
40 
41 /* Set default console usage if applicable */
42 #if ! ( defined ( CONSOLE_SERIAL ) && CONSOLE_EXPLICIT ( CONSOLE_SERIAL ) )
43 #undef CONSOLE_SERIAL
44 #define CONSOLE_SERIAL ( CONSOLE_USAGE_ALL & ~CONSOLE_USAGE_LOG )
45 #endif
46 
47 /* UART port number */
48 #ifdef COMCONSOLE
49 #define CONSOLE_PORT COMCONSOLE
50 #else
51 #define CONSOLE_PORT 0
52 #endif
53 
54 /* UART baud rate */
55 #ifdef COMPRESERVE
56 #define CONSOLE_BAUD 0
57 #else
58 #define CONSOLE_BAUD COMSPEED
59 #endif
60 
61 /* UART line control register value */
62 #ifdef COMPRESERVE
63 #define CONSOLE_LCR 0
64 #else
65 #define CONSOLE_LCR UART_LCR_WPS ( COMDATA, COMPARITY, COMSTOP )
66 #endif
67 
68 /** Serial console UART */
70 
71 /**
72  * Print a character to serial console
73  *
74  * @v character Character to be printed
75  */
76 static void serial_putchar ( int character ) {
77 
78  /* Do nothing if we have no UART */
79  if ( ! serial_console.base )
80  return;
81 
82  /* Transmit character */
83  uart_transmit ( &serial_console, character );
84 }
85 
86 /**
87  * Get character from serial console
88  *
89  * @ret character Character read from console
90  */
91 static int serial_getchar ( void ) {
92  uint8_t data;
93 
94  /* Do nothing if we have no UART */
95  if ( ! serial_console.base )
96  return 0;
97 
98  /* Wait for data to be ready */
99  while ( ! uart_data_ready ( &serial_console ) ) {}
100 
101  /* Receive data */
103 
104  /* Strip any high bit and convert DEL to backspace */
105  data &= 0x7f;
106  if ( data == 0x7f )
107  data = 0x08;
108 
109  return data;
110 }
111 
112 /**
113  * Check for character ready to read from serial console
114  *
115  * @ret True Character available to read
116  * @ret False No character available to read
117  */
118 static int serial_iskey ( void ) {
119 
120  /* Do nothing if we have no UART */
121  if ( ! serial_console.base )
122  return 0;
123 
124  /* Check UART */
125  return uart_data_ready ( &serial_console );
126 }
127 
128 /** Serial console */
129 struct console_driver serial_console_driver __console_driver = {
131  .getchar = serial_getchar,
132  .iskey = serial_iskey,
133  .usage = CONSOLE_SERIAL,
134 };
135 
136 /** Initialise serial console */
137 static void serial_init ( void ) {
138  int rc;
139 
140  /* Do nothing if we have no default port */
141  if ( ! CONSOLE_PORT )
142  return;
143 
144  /* Select UART */
145  if ( ( rc = uart_select ( &serial_console, CONSOLE_PORT ) ) != 0 ) {
146  DBG ( "Could not select UART %d: %s\n",
147  CONSOLE_PORT, strerror ( rc ) );
148  return;
149  }
150 
151  /* Initialise UART */
153  CONSOLE_LCR ) ) != 0 ) {
154  DBG ( "Could not initialise UART %d baud %d LCR %#02x: %s\n",
156  return;
157  }
158 }
159 
160 /**
161  * Shut down serial console
162  *
163  * @v flags Shutdown flags
164  */
165 static void serial_shutdown ( int flags __unused ) {
166 
167  /* Do nothing if we have no UART */
168  if ( ! serial_console.base )
169  return;
170 
171  /* Flush any pending output */
173 
174  /* Leave console enabled; it's still usable */
175 }
176 
177 /** Serial console initialisation function */
178 struct init_fn serial_console_init_fn __init_fn ( INIT_CONSOLE ) = {
180 };
181 
182 /** Serial console startup function */
183 struct startup_fn serial_startup_fn __startup_fn ( STARTUP_EARLY ) = {
184  .name = "serial",
185  .shutdown = serial_shutdown,
186 };
struct uart serial_console
Serial console UART.
Definition: serial.c:69
static void serial_init(void)
Initialise serial console.
Definition: serial.c:137
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void uart_flush(struct uart *uart)
Flush data.
Definition: uart.c:69
void(* initialise)(void)
Definition: init.h:15
#define CONSOLE_LCR
Definition: serial.c:65
A 16550-compatible UART.
Definition: uart.h:80
static int uart_data_ready(struct uart *uart)
Check if received data is ready.
Definition: uart.h:109
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
void uart_transmit(struct uart *uart, uint8_t data)
Transmit data.
Definition: uart.c:48
#define STARTUP_EARLY
Early startup.
Definition: init.h:62
void * base
I/O port base address.
Definition: uart.h:82
Serial console.
int uart_init(struct uart *uart, unsigned int baud, uint8_t lcr)
Initialise UART.
Definition: uart.c:113
static uint8_t uart_receive(struct uart *uart)
Receive data.
Definition: uart.h:122
const char * name
Definition: init.h:42
A startup/shutdown function.
Definition: init.h:41
An initialisation function.
Definition: init.h:14
void(* putchar)(int character)
Write a character to the console.
Definition: console.h:68
struct console_driver serial_console_driver __console_driver
Serial console.
Definition: serial.c:129
struct startup_fn serial_startup_fn __startup_fn(STARTUP_EARLY)
Serial console startup function.
#define CONSOLE_PORT
Definition: serial.c:51
User interaction.
static int serial_iskey(void)
Check for character ready to read from serial console.
Definition: serial.c:118
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
unsigned char uint8_t
Definition: stdint.h:10
Serial port configuration.
struct init_fn serial_console_init_fn __init_fn(INIT_CONSOLE)
Serial console initialisation function.
static void serial_shutdown(int flags __unused)
Shut down serial console.
Definition: serial.c:165
Console configuration.
static int serial_getchar(void)
Get character from serial console.
Definition: serial.c:91
#define INIT_CONSOLE
Console initialisation.
Definition: init.h:29
16550-compatible UART
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
#define CONSOLE_BAUD
Definition: serial.c:58
#define CONSOLE_SERIAL
Definition: serial.c:44
A console driver.
Definition: console.h:55
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
static void serial_putchar(int character)
Print a character to serial console.
Definition: serial.c:76
String functions.
int uart_select(struct uart *uart, unsigned int port)
Select UART port.
Definition: x86_uart.c:50
uint8_t flags
Flags.
Definition: ena.h:18