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.


85eecc84eba93736ba6d7b95c6e54966c9abe072
[palacios.git] / palacios / src / devices / serial.c
1 /*
2  * This file is part of the Palacios Virtual Machine Monitor developed
3  * by the V3VEE Project with funding from the United States National
4  * Science Foundation and the Department of Energy.
5  *
6  * The V3VEE Project is a joint project between Northwestern University
7  * and the University of New Mexico.  You can find out more at
8  * http://www.v3vee.org
9  *
10  * Copyright (c) 2010, Rumou Duan <duanrumou@gmail.com>
11  * Copyright (c) 2010, The V3VEE Project <http://www.v3vee.org>
12  * All rights reserved.
13  *
14  * Author: Rumou Duan <duanrumou@gmail.com>
15  *         Lei Xia <lxia@northwestern.edu>
16  &         Peter Dinda <pdinda@northwestern.edu>
17  *
18  * This is free software.  You are permitted to use,
19  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
20  */
21
22
23 #include <palacios/vmm.h>
24 #include <palacios/vmm_dev_mgr.h>
25 #include <palacios/vmm_types.h>
26
27 #include <palacios/vmm_ringbuffer.h>
28 #include <palacios/vmm_lock.h>
29 #include <palacios/vmm_intr.h>
30 #include <palacios/vm_guest.h>
31
32 #include <devices/serial.h>
33
34
35 #ifndef V3_CONFIG_DEBUG_SERIAL
36 #undef PrintDebug
37 #define PrintDebug(fmt, args...)
38 #endif
39
40 /*
41
42   This is an implementation of a 16450 and 16550A-compatible UART (fifo-capable), based on
43   the TI 16550D spec (http://www.ti.com/lit/ds/symlink/pc16550d.pdf) and the Altera
44   16450 spec (ftp://ftp.altera.com/pub/lit_req/document/ds/ds16450.pdf)
45
46 */
47
48 // This is not yet tested - enable at your own risk!
49 #define BE_16550A  0  
50
51
52
53 #define COM1_DATA_PORT           0x3f8
54 #define COM1_IRQ_ENABLE_PORT     0x3f9
55 #define COM1_DIV_LATCH_LSB_PORT  0x3f8
56 #define COM1_DIV_LATCH_MSB_PORT  0x3f9
57 #define COM1_IIR_PORT            0x3fa
58 #define COM1_FIFO_CTRL_PORT      0x3fa
59 #define COM1_LINE_CTRL_PORT      0x3fb
60 #define COM1_MODEM_CTRL_PORT     0x3fc
61 #define COM1_LINE_STATUS_PORT    0x3fd
62 #define COM1_MODEM_STATUS_PORT   0x3fe
63 #define COM1_SCRATCH_PORT        0x3ff
64
65 #define COM2_DATA_PORT           0x2f8
66 #define COM2_IRQ_ENABLE_PORT     0x2f9
67 #define COM2_DIV_LATCH_LSB_PORT  0x2f8
68 #define COM2_DIV_LATCH_MSB_PORT  0x2f9
69 #define COM2_IIR_PORT            0x2fa
70 #define COM2_FIFO_CTRL_PORT      0x2fa
71 #define COM2_LINE_CTRL_PORT      0x2fb
72 #define COM2_MODEM_CTRL_PORT     0x2fc
73 #define COM2_LINE_STATUS_PORT    0x2fd
74 #define COM2_MODEM_STATUS_PORT   0x2fe
75 #define COM2_SCRATCH_PORT        0x2ff
76
77 #define COM3_DATA_PORT           0x3e8
78 #define COM3_IRQ_ENABLE_PORT     0x3e9
79 #define COM3_DIV_LATCH_LSB_PORT  0x3e8
80 #define COM3_DIV_LATCH_MSB_PORT  0x3e9
81 #define COM3_IIR_PORT            0x3ea
82 #define COM3_FIFO_CTRL_PORT      0x3ea
83 #define COM3_LINE_CTRL_PORT      0x3eb
84 #define COM3_MODEM_CTRL_PORT     0x3ec
85 #define COM3_LINE_STATUS_PORT    0x3ed
86 #define COM3_MODEM_STATUS_PORT   0x3ee
87 #define COM3_SCRATCH_PORT        0x3ef
88
89 #define COM4_DATA_PORT           0x2e8
90 #define COM4_IRQ_ENABLE_PORT     0x2e9
91 #define COM4_DIV_LATCH_LSB_PORT  0x2e8
92 #define COM4_DIV_LATCH_MSB_PORT  0x2e9
93 #define COM4_IIR_PORT            0x2ea
94 #define COM4_FIFO_CTRL_PORT      0x2ea
95 #define COM4_LINE_CTRL_PORT      0x2eb
96 #define COM4_MODEM_CTRL_PORT     0x2ec
97 #define COM4_LINE_STATUS_PORT    0x2ed
98 #define COM4_MODEM_STATUS_PORT   0x2ee
99 #define COM4_SCRATCH_PORT        0x2ef
100
101
102 // Interrupt IDs (in priority order, highest is first)
103 #define RX_IRQ_STATUS           0x3
104 #define RX_IRQ_DR               0x2
105 #define RX_IRQ_TRIGGER_LEVEL    0x2
106 #define FIFO_IRQ                0x6
107 #define TX_IRQ_THRE             0x1
108 #define MODEM_IRQ_DELTA_SET     0x0
109
110 //COMs IRQ ID
111 #define COM1_IRQ  0x4
112 #define COM2_IRQ  0x3
113 #define COM3_IRQ  0x4
114 #define COM4_IRQ  0x3
115
116 #define RX_BUFFER 0x1
117 #define TX_BUFFER 0x2
118
119 //initial value for registers
120
121 // Per TI spec: http://www.ti.com/lit/ds/symlink/pc16550d.pdf
122 // all interrupt enables off
123 #define  IER_INIT_VAL 0x0 
124 // no pending interrupts (active low flag)
125 #define  IIR_INIT_VAL 0x1 
126 // fifos disabled (comes up in 16450 mode)
127 #define  FCR_INIT_VAL 0x0
128 // 5 bits, 1 stop bit, no parity, no break, divisor latch off
129 #define  LCR_INIT_VAL 0x0
130 // not DTR, not RTS, not OUT1, not OUT2, not loopback
131 #define  MCR_INIT_VAL 0x0
132 // tx registers empty, no errors, no data available
133 #define  LSR_INIT_VAL 0x60
134 // not cts, not dsr, not ring, etc.
135 #define  MSR_INIT_VAL 0x0
136 // baud rate 115200 (divisor is 1)
137 #define  DLL_INIT_VAL 0x1
138 #define  DLM_INIT_VAL 0x0
139
140 //receiver buffer register
141 struct rbr_register {
142     uint8_t data;
143 };
144
145 // transmitter holding register
146 struct thr_register {
147     uint8_t data;
148 };
149
150 //interrupt enable register
151 struct ier_register {
152     union {
153         uint8_t val;
154         struct {
155             uint8_t erbfi   : 1;  // Enable Receiver Buffer full interrupt
156             uint8_t etbei   : 1;  // Enable Transmit buffer empty interrupt
157             uint8_t elsi    : 1;  // Enable Line Status Interrupt
158             uint8_t edssi   : 1;  // Enable Delta Status signals interrupt
159             uint8_t rsvd    : 4;   // MBZ
160         } __attribute__((packed));
161     } __attribute__((packed));
162 } __attribute__((packed));
163
164
165 //interrupt identification register
166 struct iir_register {
167     union {
168         uint8_t val;
169         struct {
170             uint8_t pending : 1; // Interrupt pending (0=interrupt pending)
171             uint8_t iid     : 3; // Interrupt Identification
172             uint8_t rsvd    : 2; // MBZ
173             uint8_t fifo_en : 2; // FIFO enable
174         } __attribute__((packed));
175     } __attribute__((packed));
176 } __attribute__((packed));
177
178 //FIFO control register
179 struct fcr_register {
180     union {
181         uint8_t val;
182         struct {
183             uint8_t enable  : 1; // enable fifo
184             uint8_t rfres   : 1; // RX FIFO reset
185             uint8_t xfres   : 1; // TX FIFO reset
186             uint8_t dma_sel : 1; // DMA mode select
187             uint8_t rsvd    : 2; // MBZ
188             uint8_t rx_trigger: 2; // RX FIFO trigger level select
189         } __attribute__((packed));
190     } __attribute__((packed));
191 } __attribute__((packed));
192
193
194 //line control register
195 struct lcr_register {
196     union {
197         uint8_t val;
198         struct {
199             uint8_t word_len       : 2;  // word length select
200             uint8_t stop_bits      : 1;  // Stop Bit select
201             uint8_t parity_enable  : 1;  // Enable parity
202             uint8_t even_sel       : 1;  // Even Parity Select
203             uint8_t stick_parity   : 1;  // Stick Parity Select (e.g., force mark or space)
204             uint8_t sbr            : 1;  // Set Break
205             uint8_t dlab           : 1;  // Divisor latch access bit
206         } __attribute__((packed));
207     } __attribute__((packed));
208 } __attribute__((packed));
209
210
211 //modem control register
212 struct mcr_register {
213     union {
214         uint8_t val;
215         struct {
216             uint8_t dtr      : 1;
217             uint8_t rts      : 1;
218             uint8_t out1     : 1;
219             uint8_t out2     : 1;
220             uint8_t loop     : 1;  // loopback mode
221             uint8_t rsvd     : 3;  // MBZ
222         } __attribute__((packed));
223     } __attribute__((packed));
224 } __attribute__((packed));
225
226
227 //line status register
228 struct lsr_register {
229     union {
230         uint8_t val;
231         struct {
232             uint8_t dr      : 1;   // data ready
233             uint8_t oe       : 1;  // Overrun error
234             uint8_t pe       : 1;  // Parity Error
235             uint8_t fe       : 1;  // Framing Error
236             uint8_t brk      : 1;  // broken line detected
237             uint8_t thre     : 1;  // Transmitter holding register empty
238             uint8_t temt     : 1;  // Transmitter Empty
239             uint8_t fifo_err : 1;  // at least one error is pending in the RX FIFO chain
240         } __attribute__((packed));
241     } __attribute__((packed));
242 } __attribute__((packed));
243
244
245 struct msr_register {
246     union {
247         uint8_t val;
248         struct {
249             uint8_t dcts     : 1;  // Delta Clear To Send
250             uint8_t ddsr     : 1;  // Delta Data Set Ready
251             uint8_t teri     : 1;  // Trailing Edge Ring Indicator
252             uint8_t ddcd     : 1;  // Delta Data Carrier Detect
253             uint8_t cts      : 1;  // Clear to Send
254             uint8_t dsr      : 1;  // Data Set Ready
255             uint8_t ri       : 1;  // Ring Indicator
256             uint8_t dcd      : 1;  // Data Carrier Detect
257         } __attribute__((packed));
258     } __attribute__((packed));
259 } __attribute__((packed));
260
261 //scratch register
262 struct scr_register {
263     uint8_t data;
264 };
265
266 //divisor latch LSB
267 struct dll_register {
268     uint8_t data;
269 };
270
271 //divisor latch MSB
272 struct dlm_register {
273     uint8_t data;
274 };
275 #define SERIAL_BUF_LEN 16   
276
277 struct serial_buffer {
278     int head; // most recent data
279     int tail; // oldest char
280     int full;
281     uint8_t buffer[SERIAL_BUF_LEN];
282 };
283
284 struct serial_port {
285     struct rbr_register     rbr;
286     struct thr_register     thr;
287     struct ier_register     ier;
288     struct iir_register     iir;
289     struct fcr_register     fcr;
290     struct lcr_register     lcr;
291     struct mcr_register     mcr;
292     struct lsr_register     lsr;
293     struct msr_register     msr;
294     struct scr_register     scr;
295     struct dll_register     dll;
296     struct dlm_register     dlm;
297     
298     
299     struct serial_buffer tx_buffer;
300     struct serial_buffer rx_buffer;
301     uint_t irq_number;
302
303     /*
304       Multiple interrupt conditions can be active simultaneously. 
305       The chip does a priority encoding to determine which one shows up in the iid
306
307       INT_RX_STAT      1      line status change   cleared by LSR read
308       INT_RX_DATA      2      rx data available    cleared by RBR read or when FIFO below trigger level
309       INT_RX_TIMEOUT   2      rx fifo lonely       cleared by RBR read
310       INT_TX_EMPTY     3      tx space available   cleared by IIR read (if in iid) or write to THR
311       INT_MD_STAT      4      modem status change  cleared by MSR read
312
313     */
314 #define INT_RX_STAT     1     
315 #define INT_RX_DATA     2
316 #define INT_RX_TIMEOUT  4
317 #define INT_TX_EMPTY    8
318 #define INT_MD_STAT     16
319 #define INT_MASK        0x1f
320 // whether we currently have an IRQ raised
321 #define IRQ_RAISED_MASK  128
322
323     uint8_t int_state;  // all currently signaled interrupts, not just the one being delivered
324
325     v3_lock_t  lock;
326
327     void * backend_data;
328     struct v3_dev_char_ops * ops;
329
330 };
331
332
333 struct serial_state {
334     struct serial_port coms[4];
335
336 };
337
338
339
340 static struct serial_port * get_com_from_port(struct serial_state * serial, uint16_t port) {
341     if ((port >= COM1_DATA_PORT) && (port <= COM1_SCRATCH_PORT)) {
342         PrintDebug(VM_NONE, VCORE_NONE, "UART: COM1\n");
343         return &(serial->coms[0]);
344     } else if ((port >= COM2_DATA_PORT) && (port <= COM2_SCRATCH_PORT)) {
345         PrintDebug(VM_NONE, VCORE_NONE, "UART: COM2\n");
346         return &(serial->coms[1]);
347     } else if ((port >= COM3_DATA_PORT) && (port <= COM3_SCRATCH_PORT)) {
348         PrintDebug(VM_NONE, VCORE_NONE, "UART: COM3\n");
349         return &(serial->coms[2]);
350     } else if ((port >= COM4_DATA_PORT) && (port <= COM4_SCRATCH_PORT)) {
351         PrintDebug(VM_NONE, VCORE_NONE, "UART: COM4\n");
352         return &(serial->coms[3]);
353     } else {
354         PrintError(VM_NONE, VCORE_NONE, "UART: Error: Could not find serial port associated with IO port %d\n", port);
355         return NULL;
356     }
357 }
358
359 static inline bool receive_buffer_trigger(int number, int trigger_number) {
360
361     switch (trigger_number) {
362         case 0:
363             return (number >= 1);
364         case 1:
365             return (number >= 4);
366         case 2:
367             return (number >= 8);
368         case 3:
369             return (number >= 14);
370     }
371
372     return false;
373 }
374
375
376 static int getNumber(struct serial_buffer * buf) {
377     int number = buf->head - buf->tail;
378   
379     if (buf->full == 1) {
380         return SERIAL_BUF_LEN;
381     } else if (number >= 0) {
382         return number;
383     } else {
384         return SERIAL_BUF_LEN + number;
385     }
386 }
387
388
389                                                              
390
391 static inline int can_queue(struct serial_buffer * buf) 
392 {
393   return !(buf->full);
394 }
395
396 static inline int can_dequeue(struct serial_buffer * buf) 
397 {
398   return !( (buf->head == buf->tail) && (buf->full != 1) );
399
400 }
401
402 static inline int peek_queue(struct serial_buffer *buf, uint8_t *data)
403 {
404   int next_tail = (buf->tail + 1) % SERIAL_BUF_LEN;
405  
406   *data = buf->buffer[next_tail];
407   
408   return 0;
409 }
410
411
412 //  0 = successfully queued byte
413 // <0 = full
414 // caller responsible for locking
415 // caller responsible for updateIRQ
416 static int queue_data(struct v3_vm_info * vm, struct serial_port * com,
417                       struct serial_buffer * buf, uint8_t data) {
418     int next_loc = (buf->head + 1) % SERIAL_BUF_LEN;    
419
420     PrintDebug(vm, VCORE_NONE,"UART: queue 0x%x ('%c') to %s buffer\n", data, data, 
421                buf == &(com->rx_buffer) ? "RX" : "TX");
422
423     if (!can_queue(buf)) {
424         PrintDebug(vm, VCORE_NONE, "UART: Buffer is full!\n");
425
426         // We will not consider this an overrun, instead,
427         // we push the problem back to the caller
428
429         return -1;
430
431     } else {
432     
433         buf->buffer[next_loc] = data;
434         buf->head = next_loc;
435         
436         if (buf->head == buf->tail) {
437             buf->full = 1;
438         }
439         
440         if (buf == &(com->rx_buffer)) {
441             com->lsr.dr = 1; //as soon as new data arrives at receive buffer, set data ready bit in lsr.
442             
443             // Set INT_RX_DATA if fifo is now above trigger level or fifos are off
444             
445             if ( (com->fcr.enable && (receive_buffer_trigger( getNumber(&(com->rx_buffer)), com->fcr.rx_trigger)))   
446                  || !com->fcr.enable) {
447                 com->lsr.dr = 1;
448                 com->int_state |= INT_RX_DATA;
449
450                 PrintDebug(vm, VCORE_NONE, "UART: Set data ready and raised INT_RX_DATA\n");
451                 
452             }
453             
454         }
455         
456         if ((buf == &(com->tx_buffer))) {
457             // at least one item in the TX queue now
458             
459             com->lsr.thre = 0; //reset thre and temt bits.
460             com->lsr.temt = 0;
461             
462             // TX EMPTY deasserted 
463             com->int_state &= ~INT_TX_EMPTY;
464             
465             PrintDebug(vm, VCORE_NONE, "UART: lowered INT_TX_EMPTY\n");
466         }
467
468         return 0;
469
470     }
471     
472 }
473 //  0 = data returned
474 // <0 = data not returned
475 // caller responsible for locking
476 // caller responsible for doing updateIRQ
477 static int dequeue_data(struct v3_vm_info * vm, struct serial_port * com,
478                         struct serial_buffer * buf, uint8_t * data)
479 {
480
481
482     PrintDebug(vm, VCORE_NONE,"UART: dequeue from %s buffer\n",
483                buf == &(com->rx_buffer) ? "RX" : "TX");
484
485     if (!can_dequeue(buf)) {
486         PrintDebug(vm, VCORE_NONE, "UART: queue is empty - no state change, returning '!'\n");
487         *data='!'; // just in case it uses what's there, blindly
488         // for both rx and tx queues, we signaled when we droped to zero
489         // so we don't resignal here, so no need to call updateIRQ
490         return -1;
491     } else {
492
493         int next_tail = (buf->tail + 1) % SERIAL_BUF_LEN;
494         
495         
496         if (buf->full == 1) {
497             buf->full = 0;
498         }
499         
500         
501         *data = buf->buffer[next_tail];
502         
503         buf->buffer[next_tail] = 0;
504         buf->tail = next_tail;
505         
506         PrintDebug(vm,VCORE_NONE,"UART: dequeue will return 0x%x ('%c')\n", *data, *data);
507
508         if (buf == &(com->rx_buffer)) { 
509             
510             // Reset INT_RX_DATA if RBR read with if fifo is now below trigger level or fifos are off
511             
512             if ( (com->fcr.enable && (!receive_buffer_trigger( getNumber(&(com->rx_buffer)), com->fcr.rx_trigger)))   
513                  || !com->fcr.enable) {
514                 PrintDebug(vm, VCORE_NONE, "UART: lowering INT_RX_DATA since we're below threshold\n");
515                 com->int_state &= ~INT_RX_DATA;
516                 
517             }
518
519             // Reset DR if we have dropped to zero bytes
520             if (getNumber(&(com->rx_buffer)) ==0) { 
521                 PrintDebug(vm, VCORE_NONE, "UART: setting DR to zero since we have zero bytes\n");
522                 com->lsr.dr = 0;
523                 // should have lowered INT_RX_DATA earlier
524             }
525             
526             // reset timeout
527             com->int_state &= ~INT_RX_TIMEOUT;
528             
529         }
530         
531         if ((buf == &(com->tx_buffer)) && (getNumber(&(com->tx_buffer)) == 0)) {
532             com->lsr.thre = 1;
533             com->lsr.temt = 1;
534             
535             // Aassert TX empty when we truly drop to zero; 
536             com->int_state |= INT_TX_EMPTY;
537         }
538
539         return 0;
540     }
541 }
542
543 //
544 // Caller is assumed to have acquired the lock
545 //
546 static int pump_transmit(struct v3_vm_info * vm, struct serial_port * com) 
547 // Now we will pump transmit data to the backend, if any
548 {
549   uint8_t buf;
550   
551
552   while (can_dequeue(&(com->tx_buffer))) {
553     if (com->ops) { // do we have a back-end to toss it to?
554       int rc;
555       // let's take a peek and see if we can send it
556       peek_queue(&(com->tx_buffer),&buf);
557       rc = com->ops->output(&buf, 1, com->backend_data);
558       if (rc<0) {
559         PrintError(vm, VCORE_NONE, "UART: backend write returned error\n");
560         // we need to give up at this point - 
561         break;
562       } else if (rc==0) { 
563         // no room to send it
564         PrintDebug(vm, VCORE_NONE, "UART: backend write would block\n");
565         // we do nothing but we don't want to iterate again
566         break; // out we go
567       } else {
568         // it was sent, now we need to remove it from the queue for real
569         // as well as update the device state
570         if (dequeue_data(vm,com,&(com->tx_buffer),&buf)) { 
571           PrintError(vm, VCORE_NONE, "UART: uh... dequeue_data failed after successful peek?!\n");
572           break;  // out we go
573         }
574         // we have already sent the byte to the backend, so we
575         // just discard it now and continue to the next one
576       }
577     } else { // there is no backend
578       if (dequeue_data(vm,com,&(com->tx_buffer),&buf)) { 
579         PrintError(vm, VCORE_NONE, "UART: uh... dequeue_data failed after successful can_dequeue?!\n");
580       }
581       // no backend, so just discard the data
582     }
583   }
584   return 0;
585 }
586
587 static int updateIRQ(struct v3_vm_info * vm, struct serial_port * com) {
588
589
590
591   PrintDebug(vm,VCORE_NONE, "UART: updateIRQ before pending check: iir.pending=%d iir.iid=%d int_state=0x%x\n", 
592              com->iir.pending, com->iir.iid, com->int_state);
593
594   // if we have have raised an irq, we need to lower it if it's been handled
595   // we should also presumably lower it if the guest decided to 
596   // disable the interrupt
597   if (!com->iir.pending && (com->int_state & IRQ_RAISED_MASK)) {  // active low pending, and we have raised
598       switch (com->iir.iid) {
599           case RX_IRQ_STATUS:
600               if (!(com->int_state & INT_RX_STAT) ||                     // now low or
601                   ((com->int_state & INT_RX_STAT) && !com->ier.elsi))  { // no longer enabled
602                   // no longer asserted
603                   v3_lower_irq(vm, com->irq_number);
604                   com->int_state &= ~IRQ_RAISED_MASK;
605                   com->iir.pending=1;
606                   com->iir.iid=0;
607                   PrintDebug(vm, VCORE_NONE, "UART: lowered irq on reset of INT_RX_STAT\n");
608               }
609               break;
610           case RX_IRQ_DR:    
611           // case RX_IRQ_TRIGGER_LEVEL: is the smae
612               if (!(com->int_state & INT_RX_DATA) || 
613                   ((com->int_state & INT_RX_STAT) && !com->ier.erbfi)) {
614                   // no longer asserted
615                   v3_lower_irq(vm, com->irq_number);
616                   com->int_state &= ~IRQ_RAISED_MASK;
617                   com->iir.pending=1;
618                   com->iir.iid=0;
619                   PrintDebug(vm, VCORE_NONE, "UART: lowered irq on reset of INT_RX_DATA\n");
620               }
621               break;
622           case FIFO_IRQ:
623               if (!(com->int_state & INT_RX_TIMEOUT) ||
624                   ((com->int_state & INT_RX_TIMEOUT) && !com->ier.erbfi)) {
625                   // no longer asserted
626                   v3_lower_irq(vm, com->irq_number);
627                   com->int_state &= ~IRQ_RAISED_MASK;
628                   com->iir.pending=1;
629                   com->iir.iid=0;
630                   PrintDebug(vm, VCORE_NONE, "UART: lowered irq on reset of INT_RX_TIMEOUT\n");
631               }
632               break;
633           case TX_IRQ_THRE:
634               if (!(com->int_state & INT_TX_EMPTY)  ||
635                   ((com->int_state & INT_TX_EMPTY) && !com->ier.etbei)) {
636                   // no longer asserted
637                   v3_lower_irq(vm, com->irq_number);
638                   com->int_state &= ~IRQ_RAISED_MASK;
639                   com->iir.pending=1;
640                   com->iir.iid=0;
641                   PrintDebug(vm, VCORE_NONE, "UART: lowered irq on reset of INT_TX_EMPTY\n");
642               }
643               break;
644           case MODEM_IRQ_DELTA_SET:
645               if (!(com->int_state & INT_MD_STAT) ||
646                   ((com->int_state & INT_MD_STAT) && !com->ier.edssi)) {
647                   // no longer asserted
648                   v3_lower_irq(vm, com->irq_number);
649                   com->int_state &= ~IRQ_RAISED_MASK;
650                   com->iir.pending=1;
651                   com->iir.iid=0;
652                   PrintDebug(vm, VCORE_NONE, "UART: lowered irq on reset of INT_MD_STAT\n");
653               }
654               break;
655       }
656   }
657
658   PrintDebug(vm,VCORE_NONE, "UART: updateIRQ before transmit-pump: iir.pending=%d iir.iid=%d int_state=0x%x\n", 
659              com->iir.pending, com->iir.iid, com->int_state);
660   
661   if (pump_transmit(vm,com)) {
662     PrintError(vm,VCORE_NONE, "UART: pump_transmit failed - eh?\n");
663   }
664
665   // At this point, INT_TX_EMPTY might have also been raised
666   if (com->lsr.temt) { 
667       // even if pump_transmit wasn't able to do anything, we need to
668       // raise the interrupt - this is the case, for example, if the
669       // guest does an interrupt enable of the tx empty interrupt before
670       // writing anything
671       com->int_state |= INT_TX_EMPTY;
672   }
673
674   PrintDebug(vm,VCORE_NONE, "UART: updateIRQ before priority encode:  iir.pending=%d iir.iid=%d int_state=0x%x\n", 
675              com->iir.pending, com->iir.iid, com->int_state);
676
677
678   if (!(com->int_state & IRQ_RAISED_MASK)) { 
679       // We can inject a new interrupt since the last one is done
680       // Now we do the priority encode
681       if ((com->int_state & INT_RX_STAT) && com->ier.elsi ) { 
682           // highest priority
683           com->iir.pending=0;
684           com->iir.iid = RX_IRQ_STATUS;
685           v3_raise_irq(vm,com->irq_number);
686           com->int_state |= IRQ_RAISED_MASK;
687           PrintDebug(vm, VCORE_NONE, "UART: raised irq on set of INT_RX_STAT\n");
688       } else if ((com->int_state & INT_RX_DATA) && com->ier.erbfi) { 
689           // 2nd highest priority
690           com->iir.pending=0;
691           com->iir.iid = RX_IRQ_DR;
692           v3_raise_irq(vm,com->irq_number);
693           com->int_state |= IRQ_RAISED_MASK;
694           PrintDebug(vm, VCORE_NONE, "UART: raised irq on set of INT_RX_DATA\n");
695       } else if ((com->int_state & INT_RX_TIMEOUT) && com->ier.erbfi) { 
696           // Also 2nd highest priority
697           com->iir.pending=0;
698           com->iir.iid = FIFO_IRQ;
699           v3_raise_irq(vm,com->irq_number);
700           com->int_state |= IRQ_RAISED_MASK;
701           PrintDebug(vm, VCORE_NONE, "UART: raised irq on set of INT_RX_TIMEOUT\n");
702       } else if ((com->int_state & INT_TX_EMPTY) && com->ier.etbei) { 
703           // 3rd highest priority
704           com->iir.pending=0;
705           com->iir.iid = TX_IRQ_THRE;
706           v3_raise_irq(vm,com->irq_number);
707           com->int_state |= IRQ_RAISED_MASK;
708           PrintDebug(vm, VCORE_NONE, "UART: raised irq on set of INT_TX_EMPTY\n");
709       } else if ((com->int_state & INT_MD_STAT) && com->ier.edssi) { 
710           // 4th highest priority
711           com->iir.pending=0;
712           com->iir.iid = MODEM_IRQ_DELTA_SET;
713           v3_raise_irq(vm,com->irq_number);
714           com->int_state |= IRQ_RAISED_MASK;
715           PrintDebug(vm, VCORE_NONE, "UART: raised irq on set of INT_MD_STAT\n");
716       } else {
717           // nothing to do
718       }
719   }
720   
721   return 0;
722 }
723
724
725
726 static int write_data_port(struct guest_info * core, uint16_t port, 
727                            void * src, uint_t length, void * priv_data) {
728     struct serial_state * state = priv_data;
729     uint8_t * val = (uint8_t *)src;
730     struct serial_port * com_port = NULL;
731     addr_t irq_status;
732
733     PrintDebug(core->vm_info, core, "UART: Write to Data Port 0x%x (val=%x, '%c')\n", port, *val, *val);
734     
735     if (length != 1) {
736         PrintError(core->vm_info, core, "UART: Invalid length(%d) in write to 0x%x\n", length, port);
737         return -1;
738     }
739
740     if ((port != COM1_DATA_PORT) && (port != COM2_DATA_PORT) && 
741         (port != COM3_DATA_PORT) && (port != COM4_DATA_PORT)) {
742         PrintError(core->vm_info, core, "UART: Serial write data port for illegal port Number (%d)\n", port);
743         return -1;
744     }
745
746     com_port = get_com_from_port(state, port);
747
748     if (com_port == NULL) {
749         PrintError(core->vm_info, core, "UART: write of unknown port %d - lookup failed?!\n",port);
750         return -1;
751     }
752     
753     irq_status = v3_lock_irqsave(com_port->lock);
754     
755     // dlab is always checked first
756     if (com_port->lcr.dlab == 1) {
757         PrintDebug(core->vm_info, core, "UART:  Write to DLM, old DLM is 0x%x\n",com_port->dlm.data);
758         com_port->dll.data = *val;
759         PrintDebug(core->vm_info, core, "UART:  Write to DLM, new DLM is 0x%x\n",com_port->dlm.data);
760     }  else {
761         // queue data to send and update interrupts
762         PrintDebug(core->vm_info, core, "UART: queue transmission of 0x%x ('%c')\n",*val,*val);
763         if (queue_data(core->vm_info, com_port, &(com_port->tx_buffer), *val)) { 
764           PrintError(core->vm_info,core, "UART: no room for transmitted data - dropped\n");
765           // note that it must "succeed" since this is a device port
766         } else {
767           updateIRQ(core->vm_info, com_port);
768         }
769     }
770
771     v3_unlock_irqrestore(com_port->lock, irq_status);
772
773     return length;
774 }
775
776
777
778 static int read_data_port(struct guest_info * core, uint16_t port, 
779                           void * dst, uint_t length, void * priv_data) {
780     struct serial_state * state = priv_data;
781     uint8_t * val = (uint8_t *)dst;
782     struct serial_port * com_port = NULL;
783     addr_t irq_status;
784
785     PrintDebug(core->vm_info, core, "UART: Read from Data Port 0x%x\n", port);
786     
787     if (length != 1) {
788         PrintError(core->vm_info, core, "UART: Invalid length(%d) in write to 0x%x\n", length, port);
789         return -1;
790     }
791     
792     if ((port != COM1_DATA_PORT) && (port != COM2_DATA_PORT) && 
793         (port != COM3_DATA_PORT) && (port != COM4_DATA_PORT)) {
794         PrintError(core->vm_info, core, "UART: Serial Read data port for illegal port Number (%d)\n", port);
795         return -1;
796     }
797
798     com_port = get_com_from_port(state, port);
799
800     if (com_port == NULL) {
801         PrintError(core->vm_info, core, "UART: write of unknown port %d - lookup failed?!\n",port);
802         return -1;
803     }
804
805     irq_status = v3_lock_irqsave(com_port->lock);
806
807     if (com_port->lcr.dlab == 1) {
808         *val = com_port->dll.data;
809         PrintDebug(core->vm_info, core, "UART: read of DLL returning 0x%x\n",*val);
810     } else {
811       if (dequeue_data(core->vm_info, com_port, &(com_port->rx_buffer), val)) { 
812         PrintError(core->vm_info, core, "UART: no received data available - returning garbaage\n");
813         // note that it must "succeed" since this is device port read
814       } else {
815         updateIRQ(core->vm_info, com_port);
816       }
817       PrintDebug(core->vm_info, core, "UART: dequeued received data 0x%x ('%c')\n",*val,*val);
818     }    
819         
820     v3_unlock_irqrestore(com_port->lock, irq_status);
821
822     return length;
823 }
824
825
826 static void flush_buffer(struct serial_buffer *buf)
827 {
828     buf->head = 0;
829     buf->tail = 0;
830     buf->full = 0;
831     memset(buf->buffer, 0, SERIAL_BUF_LEN);
832 }
833
834 //
835 // caller is assumed to have acquired the lock
836 // caller is responsible for updateIRQ
837 static void handle_fcr_write(struct serial_port * com, uint8_t value) {
838
839 #if BE_16550A
840
841     if ((!com->fcr.enable && (value & 0x1)) || (com->fcr.enable && !(value & 0x1))) { 
842         // switch of modes from 16450<->16550
843         // flush fifos, reset state
844         flush_buffer(&(com->rx_buffer));
845         flush_buffer(&(com->tx_buffer));
846         com->lsr.dr = 0;
847         com->int_state &= ~INT_RX_DATA; // no data in rx buffer - lower
848
849         com->lsr.thre = 1;
850         com->lsr.temt = 1;
851         com->int_state |= INT_TX_EMPTY; // tx buffer empty - raise
852     }
853
854     if (!(value & 0x1)) { // disabling
855         // enable->disable requires flush and state reset, handled above
856         // disable->disable doesn't require flush, I don't think 
857         com->fcr.enable = 0;
858         com->iir.fifo_en = 0;
859         // reset does not change rest of fcr register
860     } else { // enabling
861         com->fcr.val = value;
862         com->fcr.rsvd = 0; // we are not some weird chip
863         
864         //if rfres set, clear receive buffer.
865         if (com->fcr.rfres == 0x1) {
866             flush_buffer(&(com->rx_buffer));
867             com->fcr.rfres = 0; // bit is self-clearing
868             com->lsr.dr = 0;
869             com->int_state &= ~INT_RX_DATA; // no data in rx buffer - lower
870         }
871         
872         //if xfres set, clear transmit buffer.
873         if (com->fcr.xfres == 0x1) {
874             flush_buffer(&(com->tx_buffer));
875             com->fcr.xfres = 0; // bit is self-clearing
876             com->lsr.thre = 1;
877             com->lsr.temt = 1;
878             com->int_state |= INT_TX_EMPTY; // tx buffer empty -raise
879         }
880
881         com->iir.fifo_en = 0x3; // We are a 16550A
882         com->iir.fifo_en = 0x0; // We are a 16450A
883
884         // 00  => 8250/16450 (latter if have scratchpad)
885         // 10  => 16550
886         // 11  => 16550A
887     }   
888
889 #else
890     // does nothing since a 16450 has no fcr
891 #endif
892
893     // caller must update irq!
894 }
895
896
897
898
899
900 static int handle_multiple(int (*func)(struct guest_info *core,
901                                        uint16_t port, void *dst,
902                                        uint_t length, void *priv_data),
903                            struct guest_info *core, uint16_t port, 
904                            void *dst, uint_t length, void *priv_data) 
905 {
906   uint16_t i;
907   int rc;
908
909   if (length == 1) { 
910     return func(core,port,dst,length,priv_data);
911   } else {
912     for (i=0;i<length;i++) {
913       rc = func(core,port+i,dst+i,1,priv_data);
914       if (rc!=1) { 
915         return i;
916       }
917     }
918     return length;
919   }
920 }
921
922 static int write_ctrl_port(struct guest_info * core, uint16_t port, void * src, 
923                            uint_t length, void * priv_data) {
924     struct serial_state * state = priv_data;
925     uint8_t val = *(uint8_t *)src;
926     struct serial_port * com_port = NULL;
927     addr_t irq_status;
928     int ret;
929
930     PrintDebug(core->vm_info, core, "UART: Write to Control Port (val=%x)\n", val);
931     
932     if (length != 1) {
933         PrintError(core->vm_info, core, "UART: Invalid Write length to control port%d\n", port);
934         return -1;
935     }
936
937     com_port = get_com_from_port(state, port);
938
939     if (com_port == NULL) {
940         PrintError(core->vm_info, core, "UART: Could not find serial port corresponding to IO port %d\n", port);
941         return -1;
942     }
943
944     irq_status = v3_lock_irqsave(com_port->lock);
945   
946     ret = 1;
947
948     //always check dlab first
949     switch (port) {
950         case COM1_IRQ_ENABLE_PORT:
951         case COM2_IRQ_ENABLE_PORT:
952         case COM3_IRQ_ENABLE_PORT:
953         case COM4_IRQ_ENABLE_PORT: {
954             PrintDebug(core->vm_info, core, "UART: Write to IER/LATCH port: dlab is %x\n", com_port->lcr.dlab);
955
956             if (com_port->lcr.dlab == 1) {
957                 PrintDebug(core->vm_info, core, "UART:  Write to DLM, old DLM is 0x%x\n",com_port->dlm.data);
958                 com_port->dlm.data = val;
959                 PrintDebug(core->vm_info, core, "UART:  Write to DLM, new DLM is 0x%x\n",com_port->dlm.data);
960             } else {
961                 PrintDebug(core->vm_info, core, "UART: Write to IER, old IER is erbfi=%d etbei=%d elsi=%d edssi=%d\n",
962                            com_port->ier.erbfi,com_port->ier.etbei,com_port->ier.elsi,com_port->ier.edssi);
963                 com_port->ier.val = val;
964                 com_port->ier.rsvd = 0; // we are not some weird chip
965                 PrintDebug(core->vm_info, core, "UART: Write to IER, new IER is erbfi=%d etbei=%d elsi=%d edssi=%d\n",
966                            com_port->ier.erbfi,com_port->ier.etbei,com_port->ier.elsi,com_port->ier.edssi);
967                 // some signaled interrupt might now need to fire
968             }
969
970             updateIRQ(core->vm_info,com_port);
971
972             break;
973         }           
974         case COM1_FIFO_CTRL_PORT:
975         case COM2_FIFO_CTRL_PORT:
976         case COM3_FIFO_CTRL_PORT:
977         case COM4_FIFO_CTRL_PORT: {
978             PrintDebug(core->vm_info, core, "UART: Write to FCR, old FCR is enable=%d rfres=%d xfres=%d dma_sel=%d rx_trigger=%d\n",
979                        com_port->fcr.enable, com_port->fcr.rfres, com_port->fcr.xfres, com_port->fcr.dma_sel, com_port->fcr.rx_trigger);
980
981             handle_fcr_write(com_port, val); // cannot fail
982             
983             PrintDebug(core->vm_info, core, "UART: Write to FCR, new FCR is enable=%d rfres=%d xfres=%d dma_sel=%d rx_trigger=%d\n",
984                        com_port->fcr.enable, com_port->fcr.rfres, com_port->fcr.xfres, com_port->fcr.dma_sel, com_port->fcr.rx_trigger);
985
986             updateIRQ(core->vm_info,com_port);
987             
988             break;
989         }
990         case COM1_LINE_CTRL_PORT:
991         case COM2_LINE_CTRL_PORT:
992         case COM3_LINE_CTRL_PORT:
993         case COM4_LINE_CTRL_PORT: {
994             PrintDebug(core->vm_info, core, "UART: Write to LCR, old LCR is word_len=%d stop_bits=%d parity_enable=%d even_sel=%d stick_parity=%d sbr=%d dlab=%d\n",
995                        com_port->lcr.word_len,com_port->lcr.stop_bits,com_port->lcr.parity_enable,com_port->lcr.even_sel,com_port->lcr.stick_parity,com_port->lcr.sbr,com_port->lcr.dlab);
996
997             com_port->lcr.val = val;
998             // no reserved bits
999             
1000             PrintDebug(core->vm_info, core, "UART: Write to LCR, new LCR is word_len=%d stop_bits=%d parity_enable=%d even_sel=%d stick_parity=%d sbr=%d dlab=%d\n",
1001                        com_port->lcr.word_len,com_port->lcr.stop_bits,com_port->lcr.parity_enable,com_port->lcr.even_sel,com_port->lcr.stick_parity,com_port->lcr.sbr,com_port->lcr.dlab);
1002
1003             updateIRQ(core->vm_info, com_port);
1004
1005             break;
1006         }
1007         case COM1_MODEM_CTRL_PORT:
1008         case COM2_MODEM_CTRL_PORT:
1009         case COM3_MODEM_CTRL_PORT:
1010         case COM4_MODEM_CTRL_PORT: {
1011             PrintDebug(core->vm_info, core, "UART: Write to MCR, old MCR is dtr=%d rts=%d out1=%d out2=%d loop=%d\n",
1012                        com_port->mcr.dtr,com_port->mcr.rts,com_port->mcr.out1,com_port->mcr.out2,com_port->mcr.loop);
1013
1014             com_port->mcr.val = val;
1015             com_port->mcr.rsvd = 0; // we are not some weird chip
1016
1017             PrintDebug(core->vm_info, core, "UART: Write to MCR, new MCR is dtr=%d rts=%d out1=%d out2=%d loop=%d\n",
1018                        com_port->mcr.dtr,com_port->mcr.rts,com_port->mcr.out1,com_port->mcr.out2,com_port->mcr.loop);
1019             
1020             updateIRQ(core->vm_info, com_port);
1021
1022             break;
1023         }
1024         case COM1_SCRATCH_PORT:
1025         case COM2_SCRATCH_PORT:
1026         case COM3_SCRATCH_PORT:
1027         case COM4_SCRATCH_PORT: {
1028             PrintDebug(core->vm_info, core, "UART: Write to SCRATCH, old value is 0x%x\n",com_port->scr.data);
1029
1030             com_port->scr.data = val;
1031
1032             PrintDebug(core->vm_info, core, "UART: Write to SCRATCH, new value is 0x%x\n",com_port->scr.data);
1033             break;
1034         }
1035         default:
1036             PrintError(core->vm_info, core, "UART: Write to unknown port %d, ERROR\n",port);
1037             ret = -1;
1038     }
1039     
1040     v3_unlock_irqrestore(com_port->lock,irq_status);
1041
1042     return ret;
1043 }
1044
1045
1046
1047
1048 static int read_ctrl_port(struct guest_info * core, uint16_t port, void * dst, 
1049                           uint_t length, void * priv_data) {
1050     struct serial_state * state = priv_data;
1051     uint8_t * val = (uint8_t *)dst;
1052     struct serial_port * com_port = NULL;
1053     addr_t irq_status;
1054     int ret;
1055
1056     PrintDebug(core->vm_info, core, "UART: Read from Control Port\n");
1057     
1058     if (length != 1) {
1059         PrintError(core->vm_info, core, "UART: Invalid Read length to control port\n");
1060         return -1;
1061     }
1062
1063     com_port = get_com_from_port(state, port);
1064
1065     if (com_port == NULL) {
1066         PrintError(core->vm_info, core, "UART: Could not find serial port corresponding to IO port %d\n", port);
1067         return -1;
1068     }
1069     
1070     irq_status = v3_lock_irqsave(com_port->lock);
1071
1072     ret = 1;
1073
1074     //always check dlab first
1075     switch (port) {
1076         case COM1_IRQ_ENABLE_PORT:
1077         case COM2_IRQ_ENABLE_PORT:
1078         case COM3_IRQ_ENABLE_PORT:
1079         case COM4_IRQ_ENABLE_PORT: {
1080             PrintDebug(core->vm_info, core, "UART: Read from IER/LATCH port: dlab is %x\n", com_port->lcr.dlab);
1081
1082             if (com_port->lcr.dlab == 1) {
1083                 PrintDebug(core->vm_info, core, "UART: Read of DLM, value 0x%x\n",com_port->dlm.data);
1084                 *val = com_port->dlm.data;
1085             } else {
1086                 *val = com_port->ier.val;
1087                 PrintDebug(core->vm_info, core, "UART: Read of IER is val=0x%x - erbfi=%d etbei=%d elsi=%d edssi=%d\n",
1088                            com_port->ier.val, com_port->ier.erbfi,com_port->ier.etbei,com_port->ier.elsi,com_port->ier.edssi);
1089             }
1090             break;
1091         }
1092
1093         case COM1_IIR_PORT:
1094         case COM2_IIR_PORT:
1095         case COM3_IIR_PORT:
1096         case COM4_IIR_PORT:
1097             PrintDebug(core->vm_info, core, "UART: read from IIR is val=0x%x - pending=%d iid=%d fifo_en=%d\n",
1098                        com_port->iir.val,com_port->iir.pending,com_port->iir.iid,com_port->iir.fifo_en);
1099             *val = com_port->iir.val;
1100
1101             if ((com_port->int_state & IRQ_RAISED_MASK) && 
1102                 !com_port->iir.pending && com_port->iir.iid==TX_IRQ_THRE) { 
1103                 // we are firing a TX_IRQ_THRE interrupt, therefore
1104                 // this read resets it
1105
1106                 com_port->int_state &= ~INT_TX_EMPTY;
1107                 
1108                 updateIRQ(core->vm_info,com_port);
1109             }
1110
1111             break;
1112
1113         case COM1_LINE_CTRL_PORT:
1114         case COM2_LINE_CTRL_PORT:
1115         case COM3_LINE_CTRL_PORT:
1116         case COM4_LINE_CTRL_PORT:
1117             PrintDebug(core->vm_info, core, "UART: read from LCR is val=0x%x - word_len=%d stop_bits=%d parity_enable=%d even_sel=%d stick_parity=%d sbr=%d dlab=%d\n",
1118                        com_port->lcr.val,com_port->lcr.word_len, com_port->lcr.stop_bits,com_port->lcr.parity_enable,com_port->lcr.even_sel,com_port->lcr.stick_parity,com_port->lcr.sbr,com_port->lcr.dlab);
1119             *val = com_port->lcr.val;
1120             break;
1121
1122         case COM1_MODEM_CTRL_PORT:
1123         case COM2_MODEM_CTRL_PORT:
1124         case COM3_MODEM_CTRL_PORT:
1125         case COM4_MODEM_CTRL_PORT:
1126             PrintDebug(core->vm_info, core, "UART: read from MCR is val=0x%x - dtr=%d rts=%d out1=%d out2=%d loop=%d\n",
1127                        com_port->mcr.val,com_port->mcr.dtr,com_port->mcr.rts,com_port->mcr.out1,com_port->mcr.out2,com_port->mcr.loop);
1128             *val = com_port->mcr.val;
1129             break;
1130
1131         case COM1_SCRATCH_PORT:
1132         case COM2_SCRATCH_PORT:
1133         case COM3_SCRATCH_PORT:
1134         case COM4_SCRATCH_PORT:
1135             PrintDebug(core->vm_info, core, "UART: read from SCRATCH is val=0x%x\n",com_port->scr.data);
1136             *val = com_port->scr.data;
1137             break;
1138
1139         default:
1140             PrintError(core->vm_info, core, "UART: read from unknown port %d\n",port);
1141             ret = -1;
1142     }
1143
1144     v3_unlock_irqrestore(com_port->lock,irq_status);
1145
1146     return ret;
1147 }
1148
1149
1150 static int write_status_port(struct guest_info * core, uint16_t port, void * src, 
1151                              uint_t length, void * priv_data) {
1152     struct serial_state * state = priv_data;
1153     uint8_t val = *(uint8_t *)src;
1154     struct serial_port * com_port = NULL;
1155     addr_t irq_status;
1156     int ret;
1157
1158     PrintDebug(core->vm_info, core, "UART: Write to Status Port (val=0x%x)\n", val);
1159
1160     if (length != 1) {
1161         PrintError(core->vm_info, core, "UART: Invalid Write length (%d) to status port %d\n", length, port);
1162         return -1;
1163     }
1164
1165     com_port = get_com_from_port(state, port);
1166
1167     if (com_port == NULL) {
1168         PrintError(core->vm_info, core, "UART: Could not find serial port corresponding to IO port %d\n", port);
1169         return -1;
1170     }
1171
1172     irq_status = v3_lock_irqsave(com_port->lock);
1173     
1174     ret = 1;
1175
1176     switch (port) {
1177         case COM1_LINE_STATUS_PORT:
1178         case COM2_LINE_STATUS_PORT:
1179         case COM3_LINE_STATUS_PORT:
1180         case COM4_LINE_STATUS_PORT:
1181             PrintDebug(core->vm_info, core, "UART: Write to LSR, old value is 0x%x - dr=%d oe=%d pe=%d fe=%d brk=%d thre=%d temt=%d fifo_err=%d\n",
1182                        com_port->lsr.val,com_port->lsr.dr,com_port->lsr.oe,com_port->lsr.pe,com_port->lsr.fe,com_port->lsr.brk,com_port->lsr.thre,com_port->lsr.temt,com_port->lsr.fifo_err);
1183
1184             com_port->lsr.val = val;
1185             // no reserved bits
1186
1187             PrintDebug(core->vm_info, core, "UART: Write to LSR, new value is 0x%x - dr=%d oe=%d pe=%d fe=%d brk=%d thre=%d temt=%d fifo_err=%d\n",
1188                        com_port->lsr.val,com_port->lsr.dr,com_port->lsr.oe,com_port->lsr.pe,com_port->lsr.fe,com_port->lsr.brk,com_port->lsr.thre,com_port->lsr.temt,com_port->lsr.fifo_err);
1189
1190             updateIRQ(core->vm_info, com_port);
1191
1192             break;
1193
1194         case COM1_MODEM_STATUS_PORT:
1195         case COM2_MODEM_STATUS_PORT:
1196         case COM3_MODEM_STATUS_PORT:
1197         case COM4_MODEM_STATUS_PORT:
1198
1199             PrintDebug(core->vm_info,core,"UART: Write to MSR, old value is 0x%x - dcts=%d ddsr=%d teri=%d ddcd=%d cts=%d dsr=%d ri=%d dcd=%d\n",
1200                        com_port->msr.val,com_port->msr.dcts,com_port->msr.ddsr,com_port->msr.teri,com_port->msr.ddcd,com_port->msr.cts,com_port->msr.dsr,com_port->msr.ri,com_port->msr.dcd);
1201
1202             com_port->msr.val = val;
1203             // no reserved bits
1204
1205             PrintDebug(core->vm_info,core,"UART: Write to MSR, new value is 0x%x - dcts=%d ddsr=%d teri=%d ddcd=%d cts=%d dsr=%d ri=%d dcd=%d\n",
1206                        com_port->msr.val,com_port->msr.dcts,com_port->msr.ddsr,com_port->msr.teri,com_port->msr.ddcd,com_port->msr.cts,com_port->msr.dsr,com_port->msr.ri,com_port->msr.dcd);
1207             
1208             updateIRQ(core->vm_info, com_port);
1209
1210             break;
1211
1212         default:
1213             PrintError(core->vm_info, core, "UART: write to unsupported port %d\n",port);
1214             ret = -1;
1215     }
1216
1217     v3_unlock_irqrestore(com_port->lock,irq_status);
1218
1219     return ret;
1220 }
1221
1222
1223 static int read_status_port(struct guest_info * core, uint16_t port, void * dst, 
1224                             uint_t length, void * priv_data) {
1225     struct serial_state * state = priv_data;
1226     uint8_t * val = (uint8_t *)dst;
1227     struct serial_port * com_port = NULL;
1228     addr_t irq_status;
1229     int ret;
1230
1231     if (length==2 && (port==COM1_MODEM_STATUS_PORT ||
1232                       port==COM2_MODEM_STATUS_PORT ||
1233                       port==COM3_MODEM_STATUS_PORT ||
1234                       port==COM4_MODEM_STATUS_PORT) ) {
1235       return handle_multiple(read_status_port,core,port,dst,length, priv_data);
1236     } else if (length!=1) { 
1237       PrintError(core->vm_info, core, "UART: Invalid Read length (%d) from status port %d\n", length, port);
1238       return -1;
1239     }
1240       
1241     PrintDebug(core->vm_info, core, "UART: Read from Status Port 0x%x\n", port);
1242
1243     com_port = get_com_from_port(state, port);
1244
1245     if (com_port == NULL) {
1246         PrintError(core->vm_info, core, "UART: Could not find serial port corresponding to IO port %d\n", port);
1247         return -1;
1248     }
1249     
1250     irq_status = v3_lock_irqsave(com_port->lock);
1251     ret = 1;
1252     
1253     switch (port) {
1254         case COM1_LINE_STATUS_PORT:
1255         case COM2_LINE_STATUS_PORT:
1256         case COM3_LINE_STATUS_PORT:
1257         case COM4_LINE_STATUS_PORT:
1258
1259             PrintDebug(core->vm_info, core, "UART: Read from LSR is 0x%x - dr=%d oe=%d pe=%d fe=%d brk=%d thre=%d temt=%d fifo_err=%d\n",
1260                        com_port->lsr.val,com_port->lsr.dr,com_port->lsr.oe,com_port->lsr.pe,com_port->lsr.fe,com_port->lsr.brk,com_port->lsr.thre,com_port->lsr.temt,com_port->lsr.fifo_err);
1261
1262             *val = com_port->lsr.val;
1263
1264
1265             // Reading the LSR resets the line error state
1266             com_port->lsr.oe = 0;     
1267             com_port->lsr.pe = 0;     
1268             com_port->lsr.fe = 0;     
1269             com_port->lsr.brk = 0;     
1270             com_port->lsr.fifo_err = 0;     
1271
1272             // and clears any interrupt we set due to it
1273             com_port->int_state &= ~INT_RX_STAT;
1274             
1275             updateIRQ(core->vm_info,com_port);
1276
1277
1278             break;
1279
1280         case COM1_MODEM_STATUS_PORT:
1281         case COM2_MODEM_STATUS_PORT:
1282         case COM3_MODEM_STATUS_PORT:
1283         case COM4_MODEM_STATUS_PORT:
1284             PrintDebug(core->vm_info,core,"UART: read of MSR is 0x%x - dcts=%d ddsr=%d teri=%d ddcd=%d cts=%d dsr=%d ri=%d dcd=%d\n",
1285                        com_port->msr.val,com_port->msr.dcts,com_port->msr.ddsr,com_port->msr.teri,com_port->msr.ddcd,com_port->msr.cts,com_port->msr.dsr,com_port->msr.ri,com_port->msr.dcd);
1286
1287             *val = com_port->msr.val;
1288
1289             // MSR read resets any interrupt due to modem error
1290             com_port->int_state &= ~INT_MD_STAT;
1291
1292             updateIRQ(core->vm_info,com_port);
1293
1294             break;
1295
1296         default:
1297             PrintError(core->vm_info, core, "UART: read of unknown port %d (length = %d)\n", port, length);
1298             ret = -1; 
1299     }
1300
1301     v3_unlock_irqrestore(com_port->lock, irq_status);
1302
1303     return ret;
1304 }
1305
1306
1307 static int deinit_serial_port(struct serial_port *);
1308
1309 static int serial_free(struct serial_state * state) {
1310
1311     deinit_serial_port(&(state->coms[0]));
1312     deinit_serial_port(&(state->coms[1]));
1313     deinit_serial_port(&(state->coms[2]));
1314     deinit_serial_port(&(state->coms[3]));
1315
1316     V3_Free(state);
1317     return 0;
1318 }
1319
1320
1321
1322 #ifdef V3_CONFIG_CHECKPOINT
1323
1324 #include <palacios/vmm_sprintf.h>
1325
1326 static int serial_buffer_save(struct v3_chkpt_ctx * ctx, int port, struct serial_buffer *sb, char * bufname) {
1327   
1328   char keyname[128];
1329   
1330   snprintf(keyname,128,"COM%d_%s_HEAD", port, bufname);
1331   V3_CHKPT_SAVE(ctx,keyname,sb->head,failout);
1332   snprintf(keyname,128,"COM%d_%s_TAIL", port, bufname);
1333   V3_CHKPT_SAVE(ctx,keyname,sb->tail,failout);
1334   snprintf(keyname,128,"COM%d_%s_FULL", port, bufname);
1335   V3_CHKPT_SAVE(ctx,keyname,sb->full,failout);
1336   snprintf(keyname,128,"COM%d_%s_DATA", port, bufname);
1337   V3_CHKPT_SAVE(ctx,keyname,sb->buffer,failout);
1338   
1339   return 0;
1340   
1341  failout:
1342   PrintError(VM_NONE, VCORE_NONE, "Failed to save serial buffer\n");
1343   return -1;
1344 }
1345
1346  
1347 static int serial_buffer_load(struct v3_chkpt_ctx * ctx, int port,  struct serial_buffer *sb, char * bufname) {
1348
1349   char keyname[128];
1350
1351   snprintf(keyname,128,"COM%d_%s_HEAD", port, bufname);
1352   V3_CHKPT_LOAD(ctx,keyname,sb->head,failout);
1353   snprintf(keyname,128,"COM%d_%s_TAIL", port, bufname);
1354   V3_CHKPT_LOAD(ctx,keyname,sb->tail,failout);
1355   snprintf(keyname,128,"COM%d_%s_FULL", port, bufname);
1356   V3_CHKPT_LOAD(ctx,keyname,sb->full,failout);
1357   snprintf(keyname,128,"COM%d_%s_DATA", port, bufname);
1358   V3_CHKPT_LOAD(ctx,keyname,sb->buffer,failout);
1359   
1360   return 0;
1361   
1362  failout:
1363   PrintError(VM_NONE, VCORE_NONE, "Failed to load serial buffer\n");
1364   return -1;
1365 }
1366  
1367 static int serial_save(struct v3_chkpt_ctx * ctx, void * private_data) {
1368   struct serial_state *state = (struct serial_state *)private_data;
1369   struct serial_port *serial;
1370   char keyname[128];
1371   int i;
1372   
1373   for (i=0;i<4;i++) { 
1374     serial = &(state->coms[i]);
1375     snprintf(keyname, 128,"COM%d_RBR",i);
1376     V3_CHKPT_SAVE(ctx, keyname, serial->rbr.data,failout);
1377     snprintf(keyname, 128,"COM%d_THR",i);
1378     V3_CHKPT_SAVE(ctx, keyname, serial->thr.data,failout);
1379     snprintf(keyname, 128,"COM%d_IER",i);
1380     V3_CHKPT_SAVE(ctx, keyname, serial->ier.val,failout);
1381     snprintf(keyname, 128,"COM%d_IIR",i);
1382     V3_CHKPT_SAVE(ctx, keyname, serial->iir.val,failout);
1383     snprintf(keyname, 128,"COM%d_FCR",i);
1384     V3_CHKPT_SAVE(ctx, keyname, serial->fcr.val,failout);
1385     snprintf(keyname, 128,"COM%d_LCR",i);
1386     V3_CHKPT_SAVE(ctx, keyname, serial->lcr.val,failout);
1387     snprintf(keyname, 128,"COM%d_MCR",i);
1388     V3_CHKPT_SAVE(ctx, keyname, serial->mcr.val,failout);
1389     snprintf(keyname, 128,"COM%d_LSR",i);
1390     V3_CHKPT_SAVE(ctx, keyname, serial->lsr.val,failout);
1391     snprintf(keyname, 128,"COM%d_MSR",i);
1392     V3_CHKPT_SAVE(ctx, keyname, serial->msr.val,failout);
1393     snprintf(keyname, 128,"COM%d_SCR",i);
1394     V3_CHKPT_SAVE(ctx, keyname, serial->scr.data,failout);
1395     snprintf(keyname, 128,"COM%d_DLL",i);
1396     V3_CHKPT_SAVE(ctx, keyname, serial->dll.data,failout);
1397     snprintf(keyname, 128,"COM%d_DLM",i);
1398     V3_CHKPT_SAVE(ctx, keyname, serial->dlm.data,failout);
1399     snprintf(keyname, 128,"COM%d_int_state",i);
1400     V3_CHKPT_SAVE(ctx, keyname, serial->int_state,failout);
1401     
1402     if (serial_buffer_save(ctx, i, &(serial->tx_buffer), "TX")) { 
1403       PrintError(VM_NONE, VCORE_NONE, "Failed to save serial tx buffer %d\n",i);
1404       goto failout;
1405     }
1406     
1407     if (serial_buffer_save(ctx, i, &(serial->rx_buffer), "RX")) { 
1408       PrintError(VM_NONE, VCORE_NONE, "Failed to save serial rx buffer %d\n",i);
1409       goto failout;
1410     }
1411     
1412     snprintf(keyname, 128,"COM%d_IRQ_NUM",i);
1413     V3_CHKPT_SAVE(ctx, keyname, serial->irq_number,failout);
1414   }
1415
1416   return 0;
1417
1418  failout:
1419   PrintError(VM_NONE, VCORE_NONE, "Failed to save serial device\n");
1420   return -1;
1421   
1422 }
1423  
1424 static int serial_load(struct v3_chkpt_ctx * ctx, void * private_data) {
1425   struct serial_state *state = (struct serial_state *)private_data;
1426   struct serial_port *serial;
1427   char keyname[128];
1428   int i;
1429   
1430   for (i=0;i<4;i++) { 
1431     serial = &(state->coms[i]);
1432     snprintf(keyname, 128,"COM%d_RBR",i);
1433     V3_CHKPT_LOAD(ctx, keyname, serial->rbr.data,failout);
1434     snprintf(keyname, 128,"COM%d_THR",i);
1435     V3_CHKPT_LOAD(ctx, keyname, serial->thr.data,failout);
1436     snprintf(keyname, 128,"COM%d_IER",i);
1437     V3_CHKPT_LOAD(ctx, keyname, serial->ier.val,failout);
1438     snprintf(keyname, 128,"COM%d_IIR",i);
1439     V3_CHKPT_LOAD(ctx, keyname, serial->iir.val,failout);
1440     snprintf(keyname, 128,"COM%d_FCR",i);
1441     V3_CHKPT_LOAD(ctx, keyname, serial->fcr.val,failout);
1442     snprintf(keyname, 128,"COM%d_LCR",i);
1443     V3_CHKPT_LOAD(ctx, keyname, serial->lcr.val,failout);
1444     snprintf(keyname, 128,"COM%d_MCR",i);
1445     V3_CHKPT_LOAD(ctx, keyname, serial->mcr.val,failout);
1446     snprintf(keyname, 128,"COM%d_LSR",i);
1447     V3_CHKPT_LOAD(ctx, keyname, serial->lsr.val,failout);
1448     snprintf(keyname, 128,"COM%d_MSR",i);
1449     V3_CHKPT_LOAD(ctx, keyname, serial->msr.val,failout);
1450     snprintf(keyname, 128,"COM%d_SCR",i);
1451     V3_CHKPT_LOAD(ctx, keyname, serial->scr.data,failout);
1452     snprintf(keyname, 128,"COM%d_DLL",i);
1453     V3_CHKPT_LOAD(ctx, keyname, serial->dll.data,failout);
1454     snprintf(keyname, 128,"COM%d_DLM",i);
1455     V3_CHKPT_LOAD(ctx, keyname, serial->dlm.data,failout);
1456     snprintf(keyname, 128,"COM%d_int_state",i);
1457     V3_CHKPT_LOAD(ctx, keyname, serial->int_state,failout);
1458
1459     if (serial_buffer_load(ctx, i, &(serial->tx_buffer), "RX")) { 
1460       PrintError(VM_NONE, VCORE_NONE, "Failed to load serial tx buffer %d\n",i);
1461       goto failout;
1462     }
1463     
1464     if (serial_buffer_load(ctx, i, &(serial->rx_buffer), "TX")) { 
1465       PrintError(VM_NONE, VCORE_NONE, "Failed to load serial rx buffer %d\n",i);
1466       goto failout;
1467     }
1468     
1469     snprintf(keyname, 128,"COM%d_IRQ_NUM",i);
1470     V3_CHKPT_LOAD(ctx, keyname, serial->irq_number,failout);
1471   }
1472
1473   return 0;
1474
1475  failout:
1476   PrintError(VM_NONE, VCORE_NONE,"Failed to load serial device\n");
1477   return -1;
1478   
1479 }
1480
1481 #endif
1482
1483 static struct v3_device_ops dev_ops = {
1484     .free = (int (*)(void *))serial_free,
1485 #ifdef V3_CONFIG_CHECKPOINT
1486     .save = serial_save, 
1487     .load = serial_load
1488 #endif
1489 };
1490
1491
1492
1493 static int init_serial_port(struct serial_port * com) {
1494
1495     // zero all
1496     memset(com, 0, sizeof(*com));
1497
1498     com->ier.val = IER_INIT_VAL;
1499     com->iir.val = IIR_INIT_VAL;
1500     com->fcr.val = FCR_INIT_VAL;
1501     com->lcr.val = LCR_INIT_VAL;
1502     com->mcr.val = MCR_INIT_VAL;
1503     com->lsr.val = LSR_INIT_VAL;
1504     com->msr.val = MSR_INIT_VAL;
1505
1506     com->dll.data =  DLL_INIT_VAL;
1507     com->dlm.data =  DLM_INIT_VAL;
1508
1509     flush_buffer(&(com->tx_buffer));
1510     flush_buffer(&(com->rx_buffer));
1511
1512     v3_lock_init(&(com->lock));
1513
1514     com->ops = NULL;
1515     com->backend_data = NULL;
1516
1517     return 0;
1518 }
1519
1520 static int deinit_serial_port(struct serial_port * com) {
1521
1522     v3_lock_deinit(&(com->lock));
1523
1524     return 0;
1525 }
1526
1527 static sint64_t serial_input(struct v3_vm_info * vm, uint8_t * buf, sint64_t len, void * priv_data){
1528     struct serial_port * com_port = (struct serial_port *)priv_data;
1529     int i;
1530     addr_t irq_status;
1531
1532     irq_status = v3_lock_irqsave(com_port->lock);
1533     
1534     for(i = 0; i < len; i++){
1535       if (queue_data(vm, com_port, &(com_port->rx_buffer), buf[i])) {
1536         break;
1537       }
1538     }
1539
1540     updateIRQ(vm, com_port);
1541
1542     v3_unlock_irqrestore(com_port->lock,irq_status);
1543
1544     return i;
1545 }
1546
1547
1548 static int connect_fn(struct v3_vm_info * vm, 
1549                       void * frontend_data, 
1550                       struct v3_dev_char_ops * ops, 
1551                       v3_cfg_tree_t * cfg, 
1552                       void * private_data, 
1553                       void ** push_fn_arg) {
1554
1555     struct serial_state * serial = (struct serial_state *)frontend_data;
1556     struct serial_port * com = NULL;
1557     char * com_port = v3_cfg_val(cfg, "com_port");
1558     int com_idx = 0;
1559
1560     if (com_port == NULL) {
1561         PrintError(vm, VCORE_NONE, "UART: Invalid Serial frontend config: missing \"com_port\"\n");
1562         return -1;
1563     }
1564     
1565     com_idx = atoi(com_port) - 1;
1566
1567     if ((com_idx > 3) || (com_idx < 0)) {
1568       PrintError(vm, VCORE_NONE, "UART: Invalid Com port (%s) \n", com_port);
1569         return -1;
1570     }
1571
1572     com = &(serial->coms[com_idx]);
1573
1574     com->ops = ops;
1575     com->backend_data = private_data;
1576
1577     com->ops->input = serial_input;
1578     *push_fn_arg = com;
1579
1580     return 0;
1581 }
1582
1583 static int serial_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
1584     struct serial_state * state = NULL;
1585     char * dev_id = v3_cfg_val(cfg, "ID");
1586     int ret = 0;
1587
1588     state = (struct serial_state *)V3_Malloc(sizeof(struct serial_state));
1589     
1590     if (state == NULL) {
1591         PrintError(vm,VCORE_NONE, "UART: Could not allocate Serial Device\n");
1592         return -1;
1593     }
1594     
1595     memset(state, 0, sizeof(struct serial_state));
1596
1597     init_serial_port(&(state->coms[0]));
1598     init_serial_port(&(state->coms[1]));
1599     init_serial_port(&(state->coms[2]));
1600     init_serial_port(&(state->coms[3]));
1601
1602     state->coms[0].irq_number = COM1_IRQ;
1603     state->coms[1].irq_number = COM2_IRQ;
1604     state->coms[2].irq_number = COM3_IRQ;
1605     state->coms[3].irq_number = COM4_IRQ;
1606
1607
1608     struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, state);
1609
1610     if (dev == NULL) {
1611         PrintError(vm, VCORE_NONE, "UART: Could not attach device %s\n", dev_id);
1612         V3_Free(state);
1613         return -1;
1614     }
1615
1616     PrintDebug(vm, VCORE_NONE, "UART: Serial device attached\n");
1617
1618     ret |= v3_dev_hook_io(dev, COM1_DATA_PORT, &read_data_port, &write_data_port);
1619     ret |= v3_dev_hook_io(dev, COM1_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port);
1620     ret |= v3_dev_hook_io(dev, COM1_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
1621     ret |= v3_dev_hook_io(dev, COM1_LINE_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
1622     ret |= v3_dev_hook_io(dev, COM1_MODEM_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
1623     ret |= v3_dev_hook_io(dev, COM1_LINE_STATUS_PORT, &read_status_port, &write_status_port);
1624     ret |= v3_dev_hook_io(dev, COM1_MODEM_STATUS_PORT, &read_status_port, &write_status_port);
1625     ret |= v3_dev_hook_io(dev, COM1_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port);
1626
1627     ret |= v3_dev_hook_io(dev, COM2_DATA_PORT, &read_data_port, &write_data_port);
1628     ret |= v3_dev_hook_io(dev, COM2_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port);
1629     ret |= v3_dev_hook_io(dev, COM2_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
1630     ret |= v3_dev_hook_io(dev, COM2_LINE_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
1631     ret |= v3_dev_hook_io(dev, COM2_MODEM_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
1632     ret |= v3_dev_hook_io(dev, COM2_LINE_STATUS_PORT, &read_status_port, &write_status_port);
1633     ret |= v3_dev_hook_io(dev, COM2_MODEM_STATUS_PORT, &read_status_port, &write_status_port);
1634     ret |= v3_dev_hook_io(dev, COM2_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port);
1635
1636     ret |= v3_dev_hook_io(dev, COM3_DATA_PORT, &read_data_port, &write_data_port);
1637     ret |= v3_dev_hook_io(dev, COM3_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port);
1638     ret |= v3_dev_hook_io(dev, COM3_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
1639     ret |= v3_dev_hook_io(dev, COM3_LINE_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
1640     ret |= v3_dev_hook_io(dev, COM3_MODEM_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
1641     ret |= v3_dev_hook_io(dev, COM3_LINE_STATUS_PORT, &read_status_port, &write_status_port);
1642     ret |= v3_dev_hook_io(dev, COM3_MODEM_STATUS_PORT, &read_status_port, &write_status_port);
1643     ret |= v3_dev_hook_io(dev, COM3_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port);
1644
1645     ret |= v3_dev_hook_io(dev, COM4_DATA_PORT, &read_data_port, &write_data_port);
1646     ret |= v3_dev_hook_io(dev, COM4_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port);
1647     ret |= v3_dev_hook_io(dev, COM4_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
1648     ret |= v3_dev_hook_io(dev, COM4_LINE_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
1649     ret |= v3_dev_hook_io(dev, COM4_MODEM_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
1650     ret |= v3_dev_hook_io(dev, COM4_LINE_STATUS_PORT, &read_status_port, &write_status_port);
1651     ret |= v3_dev_hook_io(dev, COM4_MODEM_STATUS_PORT, &read_status_port, &write_status_port);
1652     ret |= v3_dev_hook_io(dev, COM4_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port);
1653
1654     if (ret != 0) {
1655         PrintError(vm, VCORE_NONE, "UART: Error hooking Serial IO ports\n");
1656         v3_remove_device(dev);
1657         return -1;
1658     }
1659
1660     PrintDebug(vm, VCORE_NONE, "UART: Serial ports hooked\n");
1661
1662
1663
1664     if (v3_dev_add_char_frontend(vm, dev_id, connect_fn, (void *)state) == -1) {
1665         PrintError(vm, VCORE_NONE, "UART: Could not register %s as frontend\n", dev_id);
1666         v3_remove_device(dev);
1667         return -1;
1668     }
1669
1670
1671     return 0;
1672 }
1673
1674
1675
1676
1677
1678 device_register("SERIAL", serial_init)