From: Peter Dinda Date: Sat, 9 Oct 2010 01:04:42 +0000 (-0500) Subject: Implementation of stream device backend, interface to host os X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=commitdiff_plain;h=ae4e727a7abfdb7df9cb93769a0799494ec75254;p=palacios.git Implementation of stream device backend, interface to host os and partial implementation of interface to serial front end Reverted v3_start_guest to launch thread for BP on all platforms Open issue: how to make stream backend generally attachable to frontends that can support streams --- diff --git a/palacios/include/devices/serial.h b/palacios/include/devices/serial.h new file mode 100644 index 0000000..f71159c --- /dev/null +++ b/palacios/include/devices/serial.h @@ -0,0 +1,39 @@ +/* + * 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 + * Copyright (c) 2008, The V3VEE Project + * All rights reserved. + * + * Author: Jack Lange + * + * This is free software. You are permitted to use, + * redistribute, and modify it as specified in the file "V3VEE_LICENSE". + */ + +#ifndef __DEVICES_SERIAL_H__ +#define __DEVICES_SERIAL_H__ + +#ifdef __V3VEE__ + +/* Really need to find clean way to allow a backend stream device to be attachable + to different kinds of frontend devices that can act as a stream */ + +struct v3_stream_ops { + int (*read)(char *buf, uint_t len, void *private_data); + int (*write)(char *buf, uint_t len, void *private_data); +}; + + +int v3_stream_register_serial(struct vm_device * serial_dev, struct v3_stream_ops * ops, void * private_data); + +#endif // ! __V3VEE__ + + +#endif diff --git a/palacios/include/palacios/vmm_stream.h b/palacios/include/palacios/vmm_stream.h new file mode 100644 index 0000000..02b7aed --- /dev/null +++ b/palacios/include/palacios/vmm_stream.h @@ -0,0 +1,75 @@ +/* + * 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) 2010, Peter Dinda (pdinda@northwestern.edu> + * Copyright (c) 2010, The V3VEE Project + * All rights reserved. + * + * Author: Peter Dinda + * + * This is free software. You are permitted to use, + * redistribute, and modify it as specified in the file "V3VEE_LICENSE". + */ + + +#ifndef __VMM_STREAM_H__ +#define __VMM_STREAM_H__ + +#include + + +#ifdef __V3VEE__ + +#define V3_StreamOpen(path, mode) \ + ({ \ + extern struct v3_stream_hooks *stream_hooks; \ + ((stream_hooks) && (stream_hooks)->stream_open) ? \ + (stream_hooks)->stream_open((path), (mode)) : NULL; \ + }) + +#define V3_StreamRead(stream, b, l) \ + ({ \ + extern struct v3_stream_hooks *stream_hooks; \ + ((stream_hooks) && (stream_hooks)->stream_read) ? \ + (stream_hooks)->stream_read((stream), (b), (l)) : -1; \ + }) + +#define V3_StreamWrite(stream, b, l) \ + ({ \ + extern struct v3_stream_hooks *stream_hooks; \ + ((stream_hooks) && (stream_hooks)->stream_write) ? \ + (stream_hooks)->stream_write((stream), (b), (l)) : -1; \ + }) + + +#define V3_StreamClose(stream) \ + ({ \ + extern struct v3_stream_hooks *stream_hooks; \ + ((stream_hooks) && (stream_hooks)->stream_close) ? \ + (stream_hooks)->stream_close((stream), (mode)) : NULL; \ + }) + + +#endif + +#define STREAM_OPEN_MODE_READ (1 << 0) +#define STREAM_OPEN_MODE_WRITE (1 << 1) + +struct v3_stream_hooks { + void *(*stream_open)(const char *path, int mode); + int (*stream_read)(void *stream, char *buf, int len); + int (*stream_write)(void *stream, char *buf, int len); + int (*stream_close)(void *stream); + +}; + + +extern void V3_Init_Stream(struct v3_stream_hooks * hooks); + +#endif diff --git a/palacios/src/devices/serial.c b/palacios/src/devices/serial.c index b527431..961b7ea 100644 --- a/palacios/src/devices/serial.c +++ b/palacios/src/devices/serial.c @@ -28,6 +28,8 @@ #include #include +#include + #ifndef CONFIG_DEBUG_SERIAL #undef PrintDebug @@ -283,6 +285,10 @@ 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; + }; @@ -291,6 +297,8 @@ struct serial_state { struct serial_port com2; struct serial_port com3; struct serial_port com4; + + }; @@ -492,6 +500,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->stream_write(&c,1,com_port->backend_data); + } } @@ -980,5 +993,14 @@ static int serial_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { 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 */ +} + device_register("SERIAL", serial_init) diff --git a/palacios/src/devices/stream.c b/palacios/src/devices/stream.c new file mode 100644 index 0000000..e470cd9 --- /dev/null +++ b/palacios/src/devices/stream.c @@ -0,0 +1,111 @@ +/* + * 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) 2010, Peter Dinda + * Copyright (c) 2010, The V3VEE Project + * All rights reserved. + * + * Author: Peter Dinda + * + * This is free software. You are permitted to use, + * redistribute, and modify it as specified in the file "V3VEE_LICENSE". + */ + +#include +#include +#include +#include +#include +#include +#include + + +struct stream_state { + void *stream; + struct vm_device *frontend_dev; +}; + + +static int stream_read(char *buf, uint_t length, void *private_data) +{ + struct vm_device *dev = (struct vm_device *) private_data; + struct stream_state *state = (struct stream_state *) dev->private_data; + + return V3_StreamRead(state->stream,buf,length); +} + +static int stream_write(char *buf, uint_t length, void *private_data) +{ + struct vm_device *dev = (struct vm_device *) private_data; + struct stream_state *state = (struct stream_state *) dev->private_data; + + return V3_StreamWrite(state->stream,buf,length); +} + + + +static struct v3_stream_ops stream_ops = { + .write = stream_write, + .read = stream_read +}; + +static struct v3_device_ops dev_ops = { + .free = NULL, + .reset = NULL, + .start = NULL, + .stop = NULL, +}; + +static int stream_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) +{ + v3_cfg_tree_t * frontend_cfg = v3_cfg_subtree(cfg, "frontend"); + const char * frontend_tag = v3_cfg_val(frontend_cfg, "tag"); + struct vm_device * frontend = v3_find_dev(vm, frontend_tag); + char * dev_id = v3_cfg_val(cfg, "ID"); + char * path = v3_cfg_val(cfg, "localname"); + + /* read configuration */ + V3_ASSERT(frontend_cfg); + V3_ASSERT(frontend_tag); + V3_ASSERT(frontend); + + + /* allocate state */ + state = (struct cons_state *)V3_Malloc(sizeof(struct stream_state)); + V3_ASSERT(state); + state->frontend_dev = frontend; + V3_ASSERT(path); + + /* The system is responsible for interpreting the localname of the stream */ + state->stream = V3_StreamOpen(ttypath, STREAM_OPEN_MODE_READ | STREAM_OPEN_MODE_WRITE); + if (!state->stream) { + PrintError("Could not open localname %s\n", path); + V3_Free(state); + return -1; + } + + /* allocate device */ + struct vm_device *dev = v3_allocate_device(dev_id, &dev_ops, state); + V3_ASSERT(dev); + + /* attach device to virtual machine */ + if (v3_attach_device(vm, dev) == -1) { + PrintError("Could not attach device %s\n", dev_id); + V3_Free(state); + return -1; + } + + /* attach to front-end display adapter */ + v3_console_register_cga(frontend, &cons_ops, dev); + + return 0; +} + +device_register("CURSES_CONSOLE", cons_init) + diff --git a/palacios/src/palacios/vmm.c b/palacios/src/palacios/vmm.c index 2194ae5..bed92cd 100644 --- a/palacios/src/palacios/vmm.c +++ b/palacios/src/palacios/vmm.c @@ -226,22 +226,10 @@ int v3_start_vm(struct v3_vm_info * vm, unsigned int cpu_mask) { // Finally launch the BSP on core 0 sprintf(tname,"core%u",0); -#if CONFIG_LINUX - if (vm->num_cores==1) { - start_core(&(vm->cores[0])); - return -1; - } else { - if (!os_hooks->start_thread_on_cpu(0,start_core,&(vm->cores[0]),tname)) { - PrintError("Thread launch failed\n"); - return -1; - } - } -#else if (!os_hooks->start_thread_on_cpu(0,start_core,&(vm->cores[0]),tname)) { PrintError("Thread launch failed\n"); return -1; } -#endif return 0;