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