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