1 /******************************************************************************
2 * serial.h
3 *
4 * Framework for serial device drivers.
5 *
6 * Copyright (c) 2003-2008, K A Fraser
7 */
8
9 #ifndef __XEN_SERIAL_H__
10 #define __XEN_SERIAL_H__
11
12 #include <xen/init.h>
13 #include <xen/spinlock.h>
14
15 /* Register a character-receive hook on the specified COM port. */
16 typedef void (*serial_rx_fn)(char c);
17 void serial_set_rx_handler(int handle, serial_rx_fn fn);
18
19 /* Number of characters we buffer for a polling receiver. */
20 #define serial_rxbufsz 32
21
22 /* Number of characters we buffer for an interrupt-driven transmitter. */
23 extern unsigned int serial_txbufsz;
24
25 struct uart_driver;
26
27 enum serial_port_state {
28 serial_unused,
29 serial_parsed,
30 serial_initialized
31 };
32
33 struct vuart_info {
34 paddr_t base_addr; /* Base address of the UART */
35 unsigned long size; /* Size of the memory region */
36 unsigned long data_off; /* Data register offset */
37 unsigned long status_off; /* Status register offset */
38 unsigned long status; /* Ready status value */
39 };
40
41 struct serial_port {
42 /* Uart-driver parameters. */
43 struct uart_driver *driver;
44 void *uart;
45 enum serial_port_state state;
46 /* Transmit data buffer (interrupt-driven uart). */
47 char *txbuf;
48 unsigned int txbufp, txbufc;
49 bool tx_quench;
50 int tx_log_everything;
51 /* Force synchronous transmit. */
52 int sync;
53 /* Receiver callback functions (asynchronous receivers). */
54 serial_rx_fn rx_lo, rx_hi, rx;
55 /* Receive data buffer (polling receivers). */
56 char rxbuf[serial_rxbufsz];
57 unsigned int rxbufp, rxbufc;
58 /* Serial I/O is concurrency-safe. */
59 spinlock_t rx_lock, tx_lock;
60 };
61
62 struct uart_driver {
63 /* Driver initialisation (pre- and post-IRQ subsystem setup). */
64 void (*init_preirq)(struct serial_port *port);
65 void (*init_irq)(struct serial_port *port);
66 void (*init_postirq)(struct serial_port *port);
67 /* Hook to clean up after Xen bootstrap (before domain 0 runs). */
68 void (*endboot)(struct serial_port *port);
69 #ifdef CONFIG_SYSTEM_SUSPEND
70 /* Driver suspend/resume. */
71 void (*suspend)(struct serial_port *port);
72 void (*resume)(struct serial_port *port);
73 #endif
74 /* Return number of characters the port can hold for transmit,
75 * or -EIO if port is inaccesible */
76 int (*tx_ready)(struct serial_port *port);
77 /* Put a character onto the serial line. */
78 void (*putc)(struct serial_port *port, char c);
79 /* Flush accumulated characters. */
80 void (*flush)(struct serial_port *port);
81 /* Get a character from the serial line: returns 0 if none available. */
82 int (*getc)(struct serial_port *port, char *pc);
83 /* Get IRQ number for this port's serial line: returns -1 if none. */
84 int (*irq)(struct serial_port *port);
85 /* Unmask TX interrupt */
86 void (*start_tx)(struct serial_port *port);
87 /* Mask TX interrupt */
88 void (*stop_tx)(struct serial_port *port);
89 /* Get serial information */
90 const struct vuart_info *(*vuart_info)(struct serial_port *port);
91 };
92
93 /* 'Serial handles' are composed from the following fields. */
94 #define SERHND_IDX (3<<0) /* COM1, COM2, DBGP, XHCI, DTUART? */
95 # define SERHND_COM1 (0<<0)
96 # define SERHND_COM2 (1<<0)
97 # define SERHND_DBGP (2<<0)
98 # define SERHND_XHCI (3<<0)
99 # define SERHND_DTUART (0<<0) /* Steal SERHND_COM1 value */
100 #define SERHND_HI (1<<2) /* Mux/demux each transferred char by MSB. */
101 #define SERHND_LO (1<<3) /* Ditto, except that the MSB is cleared. */
102 #define SERHND_COOKED (1<<4) /* Newline/carriage-return translation? */
103
104 /* Three-stage initialisation (before/during/after IRQ-subsystem setup). */
105 void serial_init_preirq(void);
106 void serial_init_irq(void);
107 void serial_init_postirq(void);
108
109 /* Clean-up hook before domain 0 runs. */
110 void serial_endboot(void);
111
112 /* Takes a config string and creates a numeric handle on the COM port. */
113 int serial_parse_handle(const char *conf);
114
115 /* Transmit a string via the specified COM port. */
116 void serial_puts(int handle, const char *s, size_t nr);
117
118 /* Forcibly prevent serial lockup when the system is in a bad way. */
119 /* (NB. This also forces an implicit serial_start_sync()). */
120 void serial_force_unlock(int handle);
121
122 /* Start/end a synchronous region (temporarily disable interrupt-driven tx). */
123 void serial_start_sync(int handle);
124 void serial_end_sync(int handle);
125
126 /* Start/end a region where we will wait rather than drop characters. */
127 void serial_start_log_everything(int handle);
128 void serial_end_log_everything(int handle);
129
130 /* Return irq number for specified serial port (identified by index). */
131 int serial_irq(int idx);
132
133 /* Retrieve basic UART information to emulate it (base address, size...) */
134 const struct vuart_info* serial_vuart_info(int idx);
135
136 #ifdef CONFIG_SYSTEM_SUSPEND
137 /* Serial suspend/resume. */
138 void serial_suspend(void);
139 void serial_resume(void);
140 #endif
141
142 /*
143 * Initialisation and helper functions for uart drivers.
144 */
145 /* Register a uart on serial port @idx (e.g., @idx==0 is COM1). */
146 void serial_register_uart(int idx, struct uart_driver *driver, void *uart);
147 /* Place the serial port into asynchronous transmit mode. */
148 void serial_async_transmit(struct serial_port *port);
149 /* Process work in interrupt context. */
150 void serial_rx_interrupt(struct serial_port *port);
151 void serial_tx_interrupt(struct serial_port *port);
152
153 /*
154 * Initialisers for individual uart drivers.
155 */
156 /* NB. Any default value can be 0 if it is unknown and must be specified. */
157 struct ns16550_defaults {
158 int baud; /* default baud rate; BAUD_AUTO == pre-configured */
159 int data_bits; /* default data bits (5, 6, 7 or 8) */
160 int parity; /* default parity (n, o, e, m or s) */
161 int stop_bits; /* default stop bits (1 or 2) */
162 int irq; /* default irq */
163 unsigned long io_base; /* default io_base address */
164 };
165 void ns16550_init(int index, struct ns16550_defaults *defaults);
166 void ehci_dbgp_init(void);
167 #ifdef CONFIG_XHCI
168 void xhci_dbc_uart_init(void);
169 #else
xhci_dbc_uart_init(void)170 static void inline xhci_dbc_uart_init(void) {}
171 #endif
172
173 void uart_init(void);
174
175 struct physdev_dbgp_op;
176 int dbgp_op(const struct physdev_dbgp_op *op);
177
178 /* Baud rate was pre-configured before invoking the UART driver. */
179 #define BAUD_AUTO (-1)
180
181 #endif /* __XEN_SERIAL_H__ */
182
183 /*
184 * Local variables:
185 * mode: C
186 * c-file-style: "BSD"
187 * c-basic-offset: 4
188 * tab-width: 4
189 * indent-tabs-mode: nil
190 * End:
191 */
192