X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fdevices%2Fserial.c;h=1cdcc807368bfd66c7eefb63515cc43239e2b40a;hb=09a7d3811df9df65346e36419f553a38c8c45c72;hp=3f0085eded6b5ad7ca556fba4b53b64aa04c3c73;hpb=e5e029575affad90c19ca038a3b780820535d421;p=palacios-OLD.git diff --git a/palacios/src/devices/serial.c b/palacios/src/devices/serial.c index 3f0085e..1cdcc80 100644 --- a/palacios/src/devices/serial.c +++ b/palacios/src/devices/serial.c @@ -12,6 +12,7 @@ * All rights reserved. * * Author: Rumou Duan + * Lei Xia * * This is free software. You are permitted to use, * redistribute, and modify it as specified in the file "V3VEE_LICENSE". @@ -28,6 +29,14 @@ #include #include +#include + + +#ifndef CONFIG_DEBUG_SERIAL +#undef PrintDebug +#define PrintDebug(fmt, args...) +#endif + #define COM1_DATA_PORT 0x3f8 #define COM1_IRQ_ENABLE_PORT 0x3f9 @@ -277,6 +286,11 @@ struct serial_port { struct serial_buffer tx_buffer; struct serial_buffer rx_buffer; uint_t irq_number; + + struct v3_stream_ops *stream_ops; + void *backend_data; + + struct vm_device * vm_dev; }; @@ -441,19 +455,6 @@ static int dequeue_data(struct serial_buffer * buf, uint8_t * data, return 0; } -/* -static void printBuffer(struct serial_buffer * buf) { - int i = 0; - - for (i = 0; i < SERIAL_BUF_LEN; i++) { - PrintDebug(" %d ", buf->buffer[i]); - } - - PrintDebug("\n the number of elements is %d \n", getNumber(buf)); -} -*/ - -//note: write to data port is NOT implemented and corresponding codes are commented out static int write_data_port(struct guest_info * core, uint16_t port, void * src, uint_t length, struct vm_device * dev) { struct serial_state * state = (struct serial_state *)dev->private_data; @@ -486,6 +487,11 @@ static int write_data_port(struct guest_info * core, uint16_t port, com_port->dll.data = *val; } else { queue_data(&(com_port->tx_buffer), *val, com_port, dev); + if (com_port->stream_ops) { + uint8_t c; + dequeue_data(&(com_port->tx_buffer), &c, com_port, dev); + com_port->stream_ops->write(&c,1,com_port->backend_data); + } } @@ -524,8 +530,8 @@ static int read_data_port(struct guest_info * core, uint16_t port, *val = com_port->dll.data; } else { dequeue_data(&(com_port->rx_buffer), val, com_port, dev); - } - + } + return length; } @@ -912,11 +918,21 @@ static int init_serial_port(struct serial_port * com) { return 0; } +static int serial_input(char *buf, uint_t len, void *front_data){ + struct serial_port *com_port = (struct serial_port *)front_data; + int i; + + for(i=0; irx_buffer), buf[i], com_port, com_port->vm_dev); + } + + return len; +} + static int serial_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { struct serial_state * state = (struct serial_state *)V3_Malloc(sizeof(struct serial_state)); char * dev_id = v3_cfg_val(cfg, "ID"); - PrintDebug("UART: init_device\n"); init_serial_port(&(state->com1)); init_serial_port(&(state->com2)); init_serial_port(&(state->com3)); @@ -927,14 +943,19 @@ static int serial_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { state->com3.irq_number = COM3_IRQ; state->com4.irq_number = COM4_IRQ; - struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, state); - if (v3_attach_device(vm, dev) == -1) { PrintError("Could not attach device %s\n", dev_id); return -1; } + state->com1.vm_dev = dev; + state->com2.vm_dev = dev; + state->com3.vm_dev = dev; + state->com4.vm_dev = dev; + + PrintDebug("Serial device attached\n"); + 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); @@ -971,6 +992,22 @@ static int serial_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { 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); + PrintDebug("Serial ports hooked\n"); + + return 0; +} + +int v3_stream_register_serial(struct vm_device * serial_dev, struct v3_stream_ops * ops, void * private_data) +{ + struct serial_state *state = (struct serial_state *)(serial_dev->private_data); + + state->com1.stream_ops = ops; + state->com1.backend_data = private_data; + /* bind to other ports here */ + + ops->input = serial_input; + ops->front_data = &(state->com1); + return 0; }