Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


added serial port
[palacios.git] / palacios / src / devices / serial.c
1 #include <devices/serial.h>
2 #include <palacios/vmm.h>
3
4
5 #define COM1_DATA_PORT           0x3f8
6 #define COM1_IRQ_ENABLE_PORT     0x3f9
7 #define COM1_DIV_LATCH_LSB_PORT  0x3f8
8 #define COM1_DIV_LATCH_MSB_PORT  0x3f9
9 #define COM1_IIR_PORT            0x3fa
10 #define COM1_FIFO_CTRL_PORT      0x3fa
11 #define COM1_LINE_CTRL_PORT      0x3fb
12 #define COM1_MODEM_CTRL_PORT     0x3fc
13 #define COM1_LINE_STATUS_PORT    0x3fd
14 #define COM1_MODEM_STATUS_PORT   0x3fe
15 #define COM1_SCRATCH_PORT        0x3ff
16
17 #define COM2_DATA_PORT           0x2f8
18 #define COM2_IRQ_ENABLE_PORT     0x2f9
19 #define COM2_DIV_LATCH_LSB_PORT  0x2f8
20 #define COM2_DIV_LATCH_MSB_PORT  0x2f9
21 #define COM2_IIR_PORT            0x2fa
22 #define COM2_FIFO_CTRL_PORT      0x2fa
23 #define COM2_LINE_CTRL_PORT      0x2fb
24 #define COM2_MODEM_CTRL_PORT     0x2fc
25 #define COM2_LINE_STATUS_PORT    0x2fd
26 #define COM2_MODEM_STATUS_PORT   0x2fe
27 #define COM2_SCRATCH_PORT        0x2ff
28
29 #define COM3_DATA_PORT           0x3e8
30 #define COM3_IRQ_ENABLE_PORT     0x3e9
31 #define COM3_DIV_LATCH_LSB_PORT  0x3e8
32 #define COM3_DIV_LATCH_MSB_PORT  0x3e9
33 #define COM3_IIR_PORT            0x3ea
34 #define COM3_FIFO_CTRL_PORT      0x3ea
35 #define COM3_LINE_CTRL_PORT      0x3eb
36 #define COM3_MODEM_CTRL_PORT     0x3ec
37 #define COM3_LINE_STATUS_PORT    0x3ed
38 #define COM3_MODEM_STATUS_PORT   0x3ee
39 #define COM3_SCRATCH_PORT        0x3ef
40
41 #define COM4_DATA_PORT           0x2e8
42 #define COM4_IRQ_ENABLE_PORT     0x2e9
43 #define COM4_DIV_LATCH_LSB_PORT  0x2e8
44 #define COM4_DIV_LATCH_MSB_PORT  0x2e9
45 #define COM4_IIR_PORT            0x2ea
46 #define COM4_FIFO_CTRL_PORT      0x2ea
47 #define COM4_LINE_CTRL_PORT      0x2eb
48 #define COM4_MODEM_CTRL_PORT     0x2ec
49 #define COM4_LINE_STATUS_PORT    0x2ed
50 #define COM4_MODEM_STATUS_PORT   0x2ee
51 #define COM4_SCRATCH_PORT        0x2ef
52
53
54
55 struct irq_enable_reg {
56   uint_t erbfi   : 1;  // Enable Receiver Buffer full interrupt
57   uint_t etbei   : 1;  // Enable Transmit buffer empty interrupt
58   uint_t elsi    : 1;  // Enable Line Status Interrupt
59   uint_t edssi   : 1;  // Enable Delta Status signals interrupt
60   uint_t rsvd    : 4;   // MBZ
61 };
62
63
64
65 // Interrupt IDs (in priority order, highest is first)
66 #define STATUS_IRQ_LSR_OE_SET   0x3
67 #define STATUS_IRQ_LSR_PE_SET   0x3
68 #define STATUS_IRQ_LSR_FE_SET   0x3
69 #define STATUS_IRQ_LSR_BI_SET   0x3
70 #define RX_IRQ_DR               0x2
71 #define RX_IRQ_TRIGGER_LEVEL    0x2
72 #define FIFO_IRQ                0x6
73 #define TX_IRQ_THRE             0x1
74 #define MODEL_IRQ_DELTA_SET     0x0
75
76 struct irq_id_reg {
77   uint_t pending : 1; // Interrupt pending (0=interrupt pending)
78   uint_t iid     : 3; // Interrupt Identification
79   uint_t rsvd    : 2; // MBZ
80   uint_t fifo_en : 2; // FIFO enable
81 };
82
83 struct fifo_ctrl_reg {
84   uint_t enable  : 1; // enable fifo
85   uint_t rfres   : 1; // RX FIFO reset
86   uint_t xfres   : 1; // TX FIFO reset
87   uint_t dma_sel : 1; // DMA mode select
88   uint_t rsvd    : 2; // MBZ
89   uint_t rx_trigger: 2; // RX FIFO trigger level select
90 };
91
92 struct line_ctrl_reg {
93   uint_t word_len       : 2;  // word length select
94   uint_t stop_bits      : 1;  // Stop Bit select
95   uint_t parity_enable  : 1;  // Enable parity 
96   uint_t even_sel       : 1;  // Even Parity Select
97   uint_t stick_parity   : 1;  // Stick Parity Select
98   uint_t sbr            : 1;  // Set Break 
99   uint_t dlab           : 1;  // Divisor latch access bit
100 };
101
102
103 struct modem_ctrl_reg { 
104   uint_t dtr      : 1;
105   uint_t rts      : 1;
106   uint_t out1     : 1;
107   uint_t out2     : 1;
108   uint_t loop     : 1;  // loopback mode
109   uint_t rsvd     : 3;  // MBZ
110 };
111
112
113 struct line_status_reg {
114   uint_t rbf      : 1;  // Receiver Buffer Full
115   uint_t oe       : 1;  // Overrun error
116   uint_t pe       : 1;  // Parity Error
117   uint_t fe       : 1;  // Framing Error
118   uint_t brk      : 1;  // broken line detected
119   uint_t thre     : 1;  // Transmitter holding register empty
120   uint_t temt     : 1;  // Transmitter Empty
121   uint_t fifo_err : 1;  // at least one error is pending in the RX FIFO chain
122 };
123
124
125 struct modem_status_reg {
126   uint_t dcts     : 1;  // Delta Clear To Send
127   uint_t ddsr     : 1;  // Delta Data Set Ready
128   uint_t teri     : 1;  // Trailing Edge Ring Indicator
129   uint_t ddcd     : 1;  // Delta Data Carrier Detect
130   uint_t cts      : 1;  // Clear to Send
131   uint_t dsr      : 1;  // Data Set Ready
132   uint_t ri       : 1;  // Ring Indicator
133   uint_t dcd      : 1;  // Data Carrier Detect
134 };
135
136
137 struct serial_port {
138   struct irq_enable_reg     ier;
139   struct irq_id_reg         iid;
140   struct fifo_ctrl_reg      fcr;
141   struct line_ctrl_reg      lcr;
142   struct model_ctrl_reg     mcr;
143   struct line_status_reg    lsr;
144   struct model_status_reg   msr;
145
146
147   char tx_buffer[256];
148   char rx_buffer[256];
149 };
150
151
152 struct serial_state {
153   struct serial_port com1;
154   struct serial_port com2;
155   struct serial_port com3;
156   struct serial_port com4;
157 };
158
159
160 int write_data_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
161   PrintDebug("Write to Data Port\n");
162
163   return -1;
164 }
165
166 int read_data_port(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
167   PrintDebug("Read from Data Port\n");
168   return -1;
169 }
170
171
172 int write_ctrl_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
173   PrintDebug("Write to Control Port\n");
174
175   return -1;
176 }
177
178 int read_ctrl_port(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
179   PrintDebug("Read from Control Port\n");
180   return -1;
181 }
182
183
184 int write_status_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
185   PrintDebug("Write to Status Port\n");
186
187   return -1;
188 }
189
190 int read_status_port(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
191   PrintDebug("Read from Status Port\n");
192   return -1;
193 }
194
195
196
197
198
199
200
201 void serial_init(struct vm_device * dev) {
202   struct serial_state * state = (struct serial_state *)dev->private_data;
203
204   state->com1.ier.rsvd = 0;
205   state->com1.iir.rsvd = 0;
206   state->com1.fcr.rsvd = 0;
207   state->com1.mcr.rsvd = 0;
208   state->com1.iir.pending = 1;
209
210   state->com2.ier.rsvd = 0;
211   state->com2.iir.rsvd = 0;
212   state->com2.fcr.rsvd = 0;
213   state->com2.mcr.rsvd = 0;
214   state->com2.iir.pending = 1;
215
216   state->com3.ier.rsvd = 0;
217   state->com3.iir.rsvd = 0;
218   state->com3.fcr.rsvd = 0;
219   state->com3.mcr.rsvd = 0;
220   state->com3.iir.pending = 1;
221
222   state->com4.ier.rsvd = 0;
223   state->com4.iir.rsvd = 0;
224   state->com4.fcr.rsvd = 0;
225   state->com4.mcr.rsvd = 0;
226   state->com4.iir.pending = 1;
227
228
229   dev_hook_io(dev, COM1_DATA_PORT, &read_data_port, &write_data_port);
230   dev_hook_io(dev, COM1_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port);
231   dev_hook_io(dev, COM1_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
232   dev_hook_io(dev, COM1_LINE_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
233   dev_hook_io(dev, COM1_MODEL_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
234   dev_hook_io(dev, COM1_LINE_STATUS_PORT, &read_status_port, &write_status_port);
235   dev_hook_io(dev, COM1_MODEL_STATUS_PORT, &read_status_port, &write_status_port);
236   dev_hook_io(dev, COM1_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port);
237
238   dev_hook_io(dev, COM2_DATA_PORT, &read_data_port, &write_data_port);
239   dev_hook_io(dev, COM2_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port);
240   dev_hook_io(dev, COM2_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
241   dev_hook_io(dev, COM2_LINE_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
242   dev_hook_io(dev, COM2_MODEL_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
243   dev_hook_io(dev, COM2_LINE_STATUS_PORT, &read_status_port, &write_status_port);
244   dev_hook_io(dev, COM2_MODEL_STATUS_PORT, &read_status_port, &write_status_port);
245   dev_hook_io(dev, COM2_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port);
246
247   dev_hook_io(dev, COM3_DATA_PORT, &read_data_port, &write_data_port);
248   dev_hook_io(dev, COM3_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port);
249   dev_hook_io(dev, COM3_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
250   dev_hook_io(dev, COM3_LINE_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
251   dev_hook_io(dev, COM3_MODEL_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
252   dev_hook_io(dev, COM3_LINE_STATUS_PORT, &read_status_port, &write_status_port);
253   dev_hook_io(dev, COM3_MODEL_STATUS_PORT, &read_status_port, &write_status_port);
254   dev_hook_io(dev, COM3_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port);
255
256   dev_hook_io(dev, COM4_DATA_PORT, &read_data_port, &write_data_port);
257   dev_hook_io(dev, COM4_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port);
258   dev_hook_io(dev, COM4_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
259   dev_hook_io(dev, COM4_LINE_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
260   dev_hook_io(dev, COM4_MODEL_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
261   dev_hook_io(dev, COM4_LINE_STATUS_PORT, &read_status_port, &write_status_port);
262   dev_hook_io(dev, COM4_MODEL_STATUS_PORT, &read_status_port, &write_status_port);
263   dev_hook_io(dev, COM4_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port);
264
265 }
266
267
268 void serial_deinit(struct vm_device * dev) {
269
270
271   dev_unhook_io(dev, COM1_DATA_PORT);
272   dev_unhook_io(dev, COM1_IRQ_ENABLE_PORT);
273   dev_unhook_io(dev, COM1_FIFO_CTRL_PORT);
274   dev_unhook_io(dev, COM1_LINE_CTRL_PORT);
275   dev_unhook_io(dev, COM1_MODEL_CTRL_PORT);
276   dev_unhook_io(dev, COM1_LINE_STATUS_PORT);
277   dev_unhook_io(dev, COM1_MODEL_STATUS_PORT);
278   dev_unhook_io(dev, COM1_SCRATCH_PORT);
279
280   dev_unhook_io(dev, COM2_DATA_PORT);
281   dev_unhook_io(dev, COM2_IRQ_ENABLE_PORT);
282   dev_unhook_io(dev, COM2_FIFO_CTRL_PORT);
283   dev_unhook_io(dev, COM2_LINE_CTRL_PORT);
284   dev_unhook_io(dev, COM2_MODEL_CTRL_PORT);
285   dev_unhook_io(dev, COM2_LINE_STATUS_PORT);
286   dev_unhook_io(dev, COM2_MODEL_STATUS_PORT);
287   dev_unhook_io(dev, COM2_SCRATCH_PORT);
288
289   dev_unhook_io(dev, COM3_DATA_PORT);
290   dev_unhook_io(dev, COM3_IRQ_ENABLE_PORT);
291   dev_unhook_io(dev, COM3_FIFO_CTRL_PORT);
292   dev_unhook_io(dev, COM3_LINE_CTRL_PORT);
293   dev_unhook_io(dev, COM3_MODEL_CTRL_PORT);
294   dev_unhook_io(dev, COM3_LINE_STATUS_PORT);
295   dev_unhook_io(dev, COM3_MODEL_STATUS_PORT);
296   dev_unhook_io(dev, COM3_SCRATCH_PORT);
297
298   dev_unhook_io(dev, COM4_DATA_PORT);
299   dev_unhook_io(dev, COM4_IRQ_ENABLE_PORT);
300   dev_unhook_io(dev, COM4_FIFO_CTRL_PORT);
301   dev_unhook_io(dev, COM4_LINE_CTRL_PORT);
302   dev_unhook_io(dev, COM4_MODEL_CTRL_PORT);
303   dev_unhook_io(dev, COM4_LINE_STATUS_PORT);
304   dev_unhook_io(dev, COM4_MODEL_STATUS_PORT);
305   dev_unhook_io(dev, COM4_SCRATCH_PORT);
306
307 }
308
309
310
311 static struct vm_device_ops dev_ops = {
312   .init = serial_init,
313   .deinit = serial_deini,
314   .reset = NULL,
315   .start = NULL,
316   .stop = NULL,
317 };
318
319
320 struct vm_device * create_serial(int num_ports) {
321   struct serial_state * state = NULL;
322   state = (struct serial_state *)V3_Malloc(sizeof(struct serial_state));
323   V3_ASSERT(state != NULL);
324
325   struct vm_device * device = create_device("Serial UART", &dev_ops, state);
326
327   return device;
328 }