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.


fixed all the printf style warnings/errors
[palacios.git] / palacios / src / devices / serial.c
index 690123c..7468493 100644 (file)
@@ -1,3 +1,22 @@
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National 
+ * Science Foundation and the Department of Energy.  
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico.  You can find out more at 
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software.  You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
 #include <devices/serial.h>
 #include <palacios/vmm.h>
 
@@ -134,18 +153,52 @@ struct modem_status_reg {
 };
 
 
-struct serial_port {
-  struct irq_enable_reg     ier;
-  struct irq_id_reg         iid;
-  struct fifo_ctrl_reg      fcr;
-  struct line_ctrl_reg      lcr;
-  struct modem_ctrl_reg     mcr;
-  struct line_status_reg    lsr;
-  struct modem_status_reg   msr;
+#define SERIAL_BUF_LEN 256
+
+struct serial_buffer {
+  uint_t head; // most recent data
+  uint_t tail; // oldest char
+  char buffer[SERIAL_BUF_LEN];
+};
+
+static int queue_data(struct serial_buffer * buf, char data) {
+  uint_t next_loc = (buf->head + 1) % SERIAL_BUF_LEN;
+
+  if (next_loc == buf->tail) {
+    return -1;
+  }
+
+  buf->buffer[next_loc] = data;
+  buf->head = next_loc;
+
+  return 0;
+}
 
+static int dequeue_data(struct serial_buffer * buf, char * data) {
+  uint_t next_tail = (buf->tail + 1) % SERIAL_BUF_LEN;
 
-  char tx_buffer[256];
-  char rx_buffer[256];
+  if (buf->head == buf->tail) {
+    return -1;
+  }
+
+  *data = buf->buffer[buf->tail];
+  buf->tail = next_tail;
+
+  return 0;
+}
+
+
+struct serial_port {
+  char     ier;
+  char     iir;
+  char     fcr;
+  char     lcr;
+  char     mcr;
+  char     lsr;
+  char     msr;
+
+  struct serial_buffer tx_buffer;
+  struct serial_buffer rx_buffer;
 };
 
 
@@ -157,153 +210,373 @@ struct serial_state {
 };
 
 
-int write_data_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
-  PrintDebug("Write to Data Port\n");
+static int write_data_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
+  struct serial_state * state = (struct serial_state *)dev->private_data;
+  char * val = (char *)src;
+  PrintDebug("Write to Data Port 0x%x (val=%x)\n", port, *(char*)src);
+
+  if (length != 1) {
+    PrintDebug("Invalid length(%d) in write to 0x%x\n", length, port);
+    return -1;
+  }
+
+  switch (port) {
+  case COM1_DATA_PORT:
+    queue_data(&(state->com1.tx_buffer), *val);
+    break;
+  case COM2_DATA_PORT:
+    queue_data(&(state->com2.tx_buffer), *val);
+    break;
+  case COM3_DATA_PORT:
+    queue_data(&(state->com3.tx_buffer), *val);
+    break;
+  case COM4_DATA_PORT:
+    queue_data(&(state->com4.tx_buffer), *val);
+    break;
+  default:
+    return -1;
+  }
+  
+
+  return length;
+}
 
-  return -1;
+
+
+static int read_data_port(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
+  struct serial_state * state = (struct serial_state *)dev->private_data;
+  char * val = (char *)dst;
+  PrintDebug("Read from Data Port 0x%x\n", port);
+
+  if (length != 1) {
+    PrintDebug("Invalid length(%d) in write to 0x%x\n", length, port);
+    return -1;
+  }
+
+  switch (port) {
+  case COM1_DATA_PORT:
+    dequeue_data(&(state->com1.tx_buffer), val);
+    break;
+  case COM2_DATA_PORT:
+    dequeue_data(&(state->com2.tx_buffer), val);
+    break;
+  case COM3_DATA_PORT:
+    dequeue_data(&(state->com3.tx_buffer), val);
+    break;
+  case COM4_DATA_PORT:
+    dequeue_data(&(state->com4.tx_buffer), val);
+    break;
+  default:
+    return -1;
+  }
+  
+
+  return length;
 }
 
-int read_data_port(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
-  PrintDebug("Read from Data Port\n");
+
+
+static int handle_ier_write(struct serial_port * com, struct irq_enable_reg * ier) {
+  
+
   return -1;
 }
 
 
-int write_ctrl_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
-  PrintDebug("Write to Control Port\n");
+static int write_ctrl_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
+  struct serial_state * state = (struct serial_state *)dev->private_data;
+  char * val = (char *)src;
+  PrintDebug("Write to Control Port (val=%x)\n", *(char *)src);
+
+  if (length != 1) {
+    PrintDebug("Invalid Write length to control port %d\n", port);
+    return -1;
+  }
+
+  switch (port) {
+  case COM1_IRQ_ENABLE_PORT:
+    if (handle_ier_write(&(state->com1), (struct irq_enable_reg *)val) == -1) {
+      return -1;
+    }
+    break;
+  case COM2_IRQ_ENABLE_PORT:
+    if (handle_ier_write(&(state->com2), (struct irq_enable_reg *)val) == -1) {
+      return -1;
+    }
+    break;
+  case COM3_IRQ_ENABLE_PORT:
+    if (handle_ier_write(&(state->com3), (struct irq_enable_reg *)val) == -1) {
+      return -1;
+    }
+    break;
+  case COM4_IRQ_ENABLE_PORT:
+    if (handle_ier_write(&(state->com4), (struct irq_enable_reg *)val) == -1) {
+      return -1;
+    }
+    break;
+
+  case COM1_FIFO_CTRL_PORT:
+  case COM2_FIFO_CTRL_PORT:
+  case COM3_FIFO_CTRL_PORT:
+  case COM4_FIFO_CTRL_PORT:
+
+  case COM1_LINE_CTRL_PORT:
+  case COM2_LINE_CTRL_PORT:
+  case COM3_LINE_CTRL_PORT:
+  case COM4_LINE_CTRL_PORT:
+
+  case COM1_MODEM_CTRL_PORT:
+  case COM2_MODEM_CTRL_PORT:
+  case COM3_MODEM_CTRL_PORT:
+  case COM4_MODEM_CTRL_PORT:
+    
+
+
+  default:
+    return -1;
+  }
+
 
   return -1;
 }
 
-int read_ctrl_port(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
+
+
+
+static int read_ctrl_port(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
+  struct serial_state * state = (struct serial_state *)dev->private_data;
+  char * val = (char *)dst;
   PrintDebug("Read from Control Port\n");
-  return -1;
+
+  if (length != 1) {
+    PrintDebug("Invalid Read length to control port\n");
+    return -1;
+  }
+
+  switch (port) {
+  case COM1_IRQ_ENABLE_PORT:
+    *val = state->com1.ier;
+    break;
+  case COM2_IRQ_ENABLE_PORT:
+    *val = state->com2.ier;
+    break;
+  case COM3_IRQ_ENABLE_PORT:
+    *val = state->com3.ier;
+    break;
+  case COM4_IRQ_ENABLE_PORT:
+    *val = state->com4.ier;
+    break;
+
+  case COM1_FIFO_CTRL_PORT:
+    *val = state->com1.fcr;
+    break;
+  case COM2_FIFO_CTRL_PORT:
+    *val = state->com2.fcr;
+    break;
+  case COM3_FIFO_CTRL_PORT:
+    *val = state->com3.fcr;
+    break;
+  case COM4_FIFO_CTRL_PORT:
+    *val = state->com4.fcr;
+    break;
+
+  case COM1_LINE_CTRL_PORT:
+    *val = state->com1.lcr;
+    break;
+  case COM2_LINE_CTRL_PORT:
+    *val = state->com2.lcr;
+    break;
+  case COM3_LINE_CTRL_PORT:
+    *val = state->com3.lcr;
+    break;
+  case COM4_LINE_CTRL_PORT:
+    *val = state->com4.lcr;
+    break;
+
+  case COM1_MODEM_CTRL_PORT:
+    *val = state->com1.mcr;
+    break;
+  case COM2_MODEM_CTRL_PORT:
+    *val = state->com2.mcr;
+    break;
+  case COM3_MODEM_CTRL_PORT:
+    *val = state->com3.mcr;
+    break;
+  case COM4_MODEM_CTRL_PORT:
+    *val = state->com4.mcr;
+    break;
+
+  default:
+    return -1;
+  }
+
+  return length;
 }
 
 
-int write_status_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
-  PrintDebug("Write to Status Port\n");
+static int write_status_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
+  PrintDebug("Write to Status Port 0x%x (val=%x)\n", port, *(char *)src);
 
   return -1;
 }
 
-int read_status_port(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
-  PrintDebug("Read from Status Port\n");
-  return -1;
+static int read_status_port(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
+  struct serial_state * state = (struct serial_state *)dev->private_data;
+  char * val = (char *)dst;
+  PrintDebug("Read from Status Port 0x%x\n", port);
+  
+  if (length != 1) {
+    PrintDebug("Invalid Read length to control port\n");
+    return -1;
+  }
+  
+  switch (port) {
+  case COM1_LINE_STATUS_PORT:
+    *val = state->com1.lsr;
+    break;
+  case COM2_LINE_STATUS_PORT:
+    *val = state->com2.lsr;
+    break;
+  case COM3_LINE_STATUS_PORT:
+    *val = state->com3.lsr;
+    break;
+  case COM4_LINE_STATUS_PORT:
+    *val = state->com4.lsr;
+    break;
+    
+  case COM1_MODEM_STATUS_PORT:
+    *val = state->com1.msr;
+    break;
+  case COM2_MODEM_STATUS_PORT:
+    *val = state->com2.msr;
+    break;
+  case COM3_MODEM_STATUS_PORT:
+    *val = state->com3.msr;
+    break;
+  case COM4_MODEM_STATUS_PORT:
+    *val = state->com4.msr;
+    break;
+
+  default:
+    return -1;
+  }
+
+
+
+  return length;
 }
 
 
 
 
 
+static int init_serial_port(struct serial_port * com) {
+  //struct irq_enable_reg * ier = (struct irq_enable_reg *)&(com->ier);
+  //struct irq_id_reg * iir = (struct irq_id_reg *)&(com->iir);
+  //struct fifo_ctrl_reg * fcr = (struct fifo_ctrl_reg *)&(com->fcr);
+  //struct line_ctrl_reg * lcr = (struct line_ctrl_reg *)&(com->lcr);
+  //struct modem_ctrl_reg * mcr = (struct modem_ctrl_reg *)&(com->mcr);
+  //struct line_status_reg * lsr = (struct line_status_reg *)&(com->lsr);
+  //struct modem_status_reg * msr = (struct modem_status_reg *)&(com->msr);
 
+  com->ier = 0x00;
+  com->iir = 0x01;
+  com->fcr = 0x00;
+  com->lcr = 0x00;
+  com->mcr = 0x00;
+  com->lsr = 0x60;
+  com->msr = 0x00;
 
-int serial_init(struct vm_device * dev) {
+  return 0;
+}
+
+static int serial_init(struct vm_device * dev) {
   struct serial_state * state = (struct serial_state *)dev->private_data;
 
-  state->com1.ier.rsvd = 0;
-  state->com1.iid.rsvd = 0;
-  state->com1.fcr.rsvd = 0;
-  state->com1.mcr.rsvd = 0;
-  state->com1.iid.pending = 1;
-
-  state->com2.ier.rsvd = 0;
-  state->com2.iid.rsvd = 0;
-  state->com2.fcr.rsvd = 0;
-  state->com2.mcr.rsvd = 0;
-  state->com2.iid.pending = 1;
-
-  state->com3.ier.rsvd = 0;
-  state->com3.iid.rsvd = 0;
-  state->com3.fcr.rsvd = 0;
-  state->com3.mcr.rsvd = 0;
-  state->com3.iid.pending = 1;
-
-  state->com4.ier.rsvd = 0;
-  state->com4.iid.rsvd = 0;
-  state->com4.fcr.rsvd = 0;
-  state->com4.mcr.rsvd = 0;
-  state->com4.iid.pending = 1;
-
-
-  dev_hook_io(dev, COM1_DATA_PORT, &read_data_port, &write_data_port);
-  dev_hook_io(dev, COM1_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port);
-  dev_hook_io(dev, COM1_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
-  dev_hook_io(dev, COM1_LINE_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
-  dev_hook_io(dev, COM1_MODEM_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
-  dev_hook_io(dev, COM1_LINE_STATUS_PORT, &read_status_port, &write_status_port);
-  dev_hook_io(dev, COM1_MODEM_STATUS_PORT, &read_status_port, &write_status_port);
-  dev_hook_io(dev, COM1_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port);
-
-  dev_hook_io(dev, COM2_DATA_PORT, &read_data_port, &write_data_port);
-  dev_hook_io(dev, COM2_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port);
-  dev_hook_io(dev, COM2_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
-  dev_hook_io(dev, COM2_LINE_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
-  dev_hook_io(dev, COM2_MODEM_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
-  dev_hook_io(dev, COM2_LINE_STATUS_PORT, &read_status_port, &write_status_port);
-  dev_hook_io(dev, COM2_MODEM_STATUS_PORT, &read_status_port, &write_status_port);
-  dev_hook_io(dev, COM2_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port);
-
-  dev_hook_io(dev, COM3_DATA_PORT, &read_data_port, &write_data_port);
-  dev_hook_io(dev, COM3_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port);
-  dev_hook_io(dev, COM3_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
-  dev_hook_io(dev, COM3_LINE_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
-  dev_hook_io(dev, COM3_MODEM_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
-  dev_hook_io(dev, COM3_LINE_STATUS_PORT, &read_status_port, &write_status_port);
-  dev_hook_io(dev, COM3_MODEM_STATUS_PORT, &read_status_port, &write_status_port);
-  dev_hook_io(dev, COM3_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port);
-
-  dev_hook_io(dev, COM4_DATA_PORT, &read_data_port, &write_data_port);
-  dev_hook_io(dev, COM4_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port);
-  dev_hook_io(dev, COM4_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
-  dev_hook_io(dev, COM4_LINE_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
-  dev_hook_io(dev, COM4_MODEM_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
-  dev_hook_io(dev, COM4_LINE_STATUS_PORT, &read_status_port, &write_status_port);
-  dev_hook_io(dev, COM4_MODEM_STATUS_PORT, &read_status_port, &write_status_port);
-  dev_hook_io(dev, COM4_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port);
+
+  init_serial_port(&(state->com1));
+  init_serial_port(&(state->com2));
+  init_serial_port(&(state->com3));
+  init_serial_port(&(state->com4));
+
+  v3_dev_hook_io(dev, COM1_DATA_PORT, &read_data_port, &write_data_port);
+  v3_dev_hook_io(dev, COM1_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port);
+  v3_dev_hook_io(dev, COM1_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
+  v3_dev_hook_io(dev, COM1_LINE_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
+  v3_dev_hook_io(dev, COM1_MODEM_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
+  v3_dev_hook_io(dev, COM1_LINE_STATUS_PORT, &read_status_port, &write_status_port);
+  v3_dev_hook_io(dev, COM1_MODEM_STATUS_PORT, &read_status_port, &write_status_port);
+  v3_dev_hook_io(dev, COM1_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port);
+
+  v3_dev_hook_io(dev, COM2_DATA_PORT, &read_data_port, &write_data_port);
+  v3_dev_hook_io(dev, COM2_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port);
+  v3_dev_hook_io(dev, COM2_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
+  v3_dev_hook_io(dev, COM2_LINE_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
+  v3_dev_hook_io(dev, COM2_MODEM_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
+  v3_dev_hook_io(dev, COM2_LINE_STATUS_PORT, &read_status_port, &write_status_port);
+  v3_dev_hook_io(dev, COM2_MODEM_STATUS_PORT, &read_status_port, &write_status_port);
+  v3_dev_hook_io(dev, COM2_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port);
+
+  v3_dev_hook_io(dev, COM3_DATA_PORT, &read_data_port, &write_data_port);
+  v3_dev_hook_io(dev, COM3_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port);
+  v3_dev_hook_io(dev, COM3_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
+  v3_dev_hook_io(dev, COM3_LINE_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
+  v3_dev_hook_io(dev, COM3_MODEM_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
+  v3_dev_hook_io(dev, COM3_LINE_STATUS_PORT, &read_status_port, &write_status_port);
+  v3_dev_hook_io(dev, COM3_MODEM_STATUS_PORT, &read_status_port, &write_status_port);
+  v3_dev_hook_io(dev, COM3_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port);
+
+  v3_dev_hook_io(dev, COM4_DATA_PORT, &read_data_port, &write_data_port);
+  v3_dev_hook_io(dev, COM4_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port);
+  v3_dev_hook_io(dev, COM4_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
+  v3_dev_hook_io(dev, COM4_LINE_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
+  v3_dev_hook_io(dev, COM4_MODEM_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
+  v3_dev_hook_io(dev, COM4_LINE_STATUS_PORT, &read_status_port, &write_status_port);
+  v3_dev_hook_io(dev, COM4_MODEM_STATUS_PORT, &read_status_port, &write_status_port);
+  v3_dev_hook_io(dev, COM4_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port);
 
   return 0;
 }
 
 
-int serial_deinit(struct vm_device * dev) {
-
-
-  dev_unhook_io(dev, COM1_DATA_PORT);
-  dev_unhook_io(dev, COM1_IRQ_ENABLE_PORT);
-  dev_unhook_io(dev, COM1_FIFO_CTRL_PORT);
-  dev_unhook_io(dev, COM1_LINE_CTRL_PORT);
-  dev_unhook_io(dev, COM1_MODEM_CTRL_PORT);
-  dev_unhook_io(dev, COM1_LINE_STATUS_PORT);
-  dev_unhook_io(dev, COM1_MODEM_STATUS_PORT);
-  dev_unhook_io(dev, COM1_SCRATCH_PORT);
-
-  dev_unhook_io(dev, COM2_DATA_PORT);
-  dev_unhook_io(dev, COM2_IRQ_ENABLE_PORT);
-  dev_unhook_io(dev, COM2_FIFO_CTRL_PORT);
-  dev_unhook_io(dev, COM2_LINE_CTRL_PORT);
-  dev_unhook_io(dev, COM2_MODEM_CTRL_PORT);
-  dev_unhook_io(dev, COM2_LINE_STATUS_PORT);
-  dev_unhook_io(dev, COM2_MODEM_STATUS_PORT);
-  dev_unhook_io(dev, COM2_SCRATCH_PORT);
-
-  dev_unhook_io(dev, COM3_DATA_PORT);
-  dev_unhook_io(dev, COM3_IRQ_ENABLE_PORT);
-  dev_unhook_io(dev, COM3_FIFO_CTRL_PORT);
-  dev_unhook_io(dev, COM3_LINE_CTRL_PORT);
-  dev_unhook_io(dev, COM3_MODEM_CTRL_PORT);
-  dev_unhook_io(dev, COM3_LINE_STATUS_PORT);
-  dev_unhook_io(dev, COM3_MODEM_STATUS_PORT);
-  dev_unhook_io(dev, COM3_SCRATCH_PORT);
-
-  dev_unhook_io(dev, COM4_DATA_PORT);
-  dev_unhook_io(dev, COM4_IRQ_ENABLE_PORT);
-  dev_unhook_io(dev, COM4_FIFO_CTRL_PORT);
-  dev_unhook_io(dev, COM4_LINE_CTRL_PORT);
-  dev_unhook_io(dev, COM4_MODEM_CTRL_PORT);
-  dev_unhook_io(dev, COM4_LINE_STATUS_PORT);
-  dev_unhook_io(dev, COM4_MODEM_STATUS_PORT);
-  dev_unhook_io(dev, COM4_SCRATCH_PORT);
+static int serial_deinit(struct vm_device * dev) {
+
+
+  v3_dev_unhook_io(dev, COM1_DATA_PORT);
+  v3_dev_unhook_io(dev, COM1_IRQ_ENABLE_PORT);
+  v3_dev_unhook_io(dev, COM1_FIFO_CTRL_PORT);
+  v3_dev_unhook_io(dev, COM1_LINE_CTRL_PORT);
+  v3_dev_unhook_io(dev, COM1_MODEM_CTRL_PORT);
+  v3_dev_unhook_io(dev, COM1_LINE_STATUS_PORT);
+  v3_dev_unhook_io(dev, COM1_MODEM_STATUS_PORT);
+  v3_dev_unhook_io(dev, COM1_SCRATCH_PORT);
+
+  v3_dev_unhook_io(dev, COM2_DATA_PORT);
+  v3_dev_unhook_io(dev, COM2_IRQ_ENABLE_PORT);
+  v3_dev_unhook_io(dev, COM2_FIFO_CTRL_PORT);
+  v3_dev_unhook_io(dev, COM2_LINE_CTRL_PORT);
+  v3_dev_unhook_io(dev, COM2_MODEM_CTRL_PORT);
+  v3_dev_unhook_io(dev, COM2_LINE_STATUS_PORT);
+  v3_dev_unhook_io(dev, COM2_MODEM_STATUS_PORT);
+  v3_dev_unhook_io(dev, COM2_SCRATCH_PORT);
+
+  v3_dev_unhook_io(dev, COM3_DATA_PORT);
+  v3_dev_unhook_io(dev, COM3_IRQ_ENABLE_PORT);
+  v3_dev_unhook_io(dev, COM3_FIFO_CTRL_PORT);
+  v3_dev_unhook_io(dev, COM3_LINE_CTRL_PORT);
+  v3_dev_unhook_io(dev, COM3_MODEM_CTRL_PORT);
+  v3_dev_unhook_io(dev, COM3_LINE_STATUS_PORT);
+  v3_dev_unhook_io(dev, COM3_MODEM_STATUS_PORT);
+  v3_dev_unhook_io(dev, COM3_SCRATCH_PORT);
+
+  v3_dev_unhook_io(dev, COM4_DATA_PORT);
+  v3_dev_unhook_io(dev, COM4_IRQ_ENABLE_PORT);
+  v3_dev_unhook_io(dev, COM4_FIFO_CTRL_PORT);
+  v3_dev_unhook_io(dev, COM4_LINE_CTRL_PORT);
+  v3_dev_unhook_io(dev, COM4_MODEM_CTRL_PORT);
+  v3_dev_unhook_io(dev, COM4_LINE_STATUS_PORT);
+  v3_dev_unhook_io(dev, COM4_MODEM_STATUS_PORT);
+  v3_dev_unhook_io(dev, COM4_SCRATCH_PORT);
 
   return 0;
 }
@@ -319,12 +592,12 @@ static struct vm_device_ops dev_ops = {
 };
 
 
-struct vm_device * create_serial(int num_ports) {
+struct vm_device * v3_create_serial(int num_ports) {
   struct serial_state * state = NULL;
   state = (struct serial_state *)V3_Malloc(sizeof(struct serial_state));
   V3_ASSERT(state != NULL);
 
-  struct vm_device * device = create_device("Serial UART", &dev_ops, state);
+  struct vm_device * device = v3_create_device("Serial UART", &dev_ops, state);
 
   return device;
 }