The console is still a complete mess, but my attempt to fix it just made it stop working.
uint8_t dst;
} __attribute__((packed));
-int v3_apic_send_ipi(struct v3_vm_info * vm, struct vm_device * dev,
- struct v3_gen_ipi * ipi);
+int v3_apic_send_ipi(struct v3_vm_info * vm, struct v3_gen_ipi * ipi, void * dev_data);
-int v3_apic_raise_intr(struct v3_vm_info * vm, struct vm_device * apic_dev,
- uint32_t irq, uint32_t dst);
+int v3_apic_raise_intr(struct v3_vm_info * vm,
+ uint32_t irq, uint32_t dst,
+ void * dev_data);
-int v3_ide_get_geometry(struct vm_device * ide_dev, int channel_num, int drive_num,
+int v3_ide_get_geometry(void * ide_data, int channel_num, int drive_num,
uint32_t * cylinders, uint32_t * heads, uint32_t * sectors);
int v3_pci_set_irq_bridge(struct vm_device * pci_bus, int bus_num,
- int (*raise_pci_irq)(struct vm_device * dev, struct pci_device * pci_dev),
- int (*lower_pci_irq)(struct vm_device * dev, struct pci_device * pci_dev),
- struct vm_device * bridge_dev);
+ int (*raise_pci_irq)(struct pci_device * pci_dev, void * dev_data),
+ int (*lower_pci_irq)(struct pci_device * pci_dev, void * dev_data),
+ void * dev_data);
int v3_pci_raise_irq(struct vm_device * pci_bus, int bus_num, struct pci_device * dev);
typedef enum {V3_SB_INVALID, V3_SB_PIIX3, V3_SB_PIIX4, V3_SB_CMD646} v3_southbridge_type_t;
+struct v3_vm_info;
+
struct v3_southbridge {
struct vm_device * pci_bus;
struct pci_device * southbridge_pci;
+ struct v3_vm_info * vm;
+
v3_southbridge_type_t type;
};
struct v3_device_ops;
+typedef void * v3_dev_data_t;
+
+struct vm_device;
struct vm_device {
char name[32];
struct list_head char_list;
struct hashtable * char_table;
- struct list_head console_list;
- struct hashtable * console_table;
+ struct list_head cons_list;
+ struct hashtable * cons_table;
};
struct v3_device_ops {
- int (*free)(struct vm_device *dev);
-
-
- int (*reset)(struct vm_device *dev);
-
- int (*start)(struct vm_device *dev);
- int (*stop)(struct vm_device *dev);
-
+ int (*free)(struct vm_device * dev);
//int (*save)(struct vm_device *dev, struct *iostream);
//int (*restore)(struct vm_device *dev, struct *iostream);
int (*read)(struct guest_info * core, ushort_t port, void * dst, uint_t length, void * priv_data),
int (*write)(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data));
-int v3_dev_unhook_io(struct vm_device *dev,
+int v3_dev_unhook_io(struct vm_device * dev,
ushort_t port);
struct v3_dev_net_ops {
/* Backend implemented functions */
- int (*send)(uint8_t * buf, uint32_t count, void * private_data, struct vm_device *dest_dev);
- void (*start_rx)(void *back_data);
- void (*stop_rx)(void *back_data);
+ int (*send)(uint8_t * buf, uint32_t count, void * private_data);
+ void (*start_rx)(void * back_data);
+ void (*stop_rx)(void * back_data);
/* Frontend implemented functions */
int (*recv)(uint8_t * buf, uint32_t count, void * frnt_data);
};
struct v3_dev_console_ops {
+ int (*update_screen)(uint_t x, uint_t y, uint_t length, uint8_t * fb_data, void * private_data);
+ int (*update_cursor)(uint_t x, uint_t y, void * private_data);
+ int (*scroll)(int rows, void * private_data);
+ /* frontend implemented functions */
+ int (*get_screen)(uint_t x, uint_t y, uint_t length, void * frontend_data);
+ void * push_fn_arg;
};
struct v3_dev_char_ops {
void * private_data);
+
+
+int v3_dev_add_console_frontend(struct v3_vm_info * vm,
+ char * name,
+ int (*connect)(struct v3_vm_info * vm,
+ void * frontend_data,
+ struct v3_dev_console_ops * ops,
+ v3_cfg_tree_t * cfg,
+ void * private_data),
+ void * priv_data);
+
+int v3_dev_connect_console(struct v3_vm_info * vm,
+ char * frontend_name,
+ struct v3_dev_console_ops * ops,
+ v3_cfg_tree_t * cfg,
+ void * private_data);
+
+
+
int v3_dev_add_char_frontend(struct v3_vm_info * vm,
char * name,
int (*connect)(struct v3_vm_info * vm,
* This should call out to handle_SQR_WAVE_tics, etc...
*/
// Returns true if the the output signal changed state
-static int handle_crystal_tics(struct vm_device * dev, struct channel * ch, uint_t oscillations) {
+static int handle_crystal_tics(struct pit * pit, struct channel * ch, uint_t oscillations) {
uint_t channel_cycles = 0;
uint_t output_changed = 0;
#include <palacios/vm_guest.h>
static void pit_update_timer(struct guest_info * info, ullong_t cpu_cycles, ullong_t cpu_freq, void * private_data) {
- struct vm_device * dev = (struct vm_device *)private_data;
- struct pit * state = (struct pit *)dev->private_data;
+ struct pit * state = (struct pit *)private_data;
// ullong_t tmp_ctr = state->pit_counter;
ullong_t tmp_cycles;
uint_t oscillations = 0;
state->pit_counter = state->pit_reload - cpu_cycles;
//PrintDebug("8254 PIT: Handling %d crystal tics\n", oscillations);
- if (handle_crystal_tics(dev, &(state->ch_0), oscillations) == 1) {
+ if (handle_crystal_tics(state, &(state->ch_0), oscillations) == 1) {
// raise interrupt
PrintDebug("8254 PIT: Injecting Timer interrupt to guest\n");
v3_raise_irq(info->vm_info, 0);
}
- //handle_crystal_tics(dev, &(state->ch_1), oscillations);
- handle_crystal_tics(dev, &(state->ch_2), oscillations);
+ //handle_crystal_tics(state, &(state->ch_1), oscillations);
+ handle_crystal_tics(state, &(state->ch_2), oscillations);
}
static struct v3_device_ops dev_ops = {
.free = pit_free,
- .reset = NULL,
- .start = NULL,
- .stop = NULL,
+
};
- pit_state->timer = v3_add_timer(info, &timer_ops, dev);
+ pit_state->timer = v3_add_timer(info, &timer_ops, pit_state);
if (pit_state->timer == NULL) {
v3_detach_device(dev);
static int pic_free(struct vm_device * dev) {
- v3_dev_unhook_io(dev, MASTER_PORT1);
- v3_dev_unhook_io(dev, MASTER_PORT2);
- v3_dev_unhook_io(dev, SLAVE_PORT1);
- v3_dev_unhook_io(dev, SLAVE_PORT2);
return 0;
}
static struct v3_device_ops dev_ops = {
.free = pic_free,
- .reset = NULL,
- .start = NULL,
- .stop = NULL,
+
};
#endif
#ifdef CONFIG_DEBUG_APIC
-static char *shorthand_str[] = {
+static char * shorthand_str[] = {
"(no shorthand)",
"(self)",
"(all)",
"(all-but-me)",
};
-static char *deliverymode_str[] = {
+static char * deliverymode_str[] = {
"(fixed)",
"(lowest priority)",
"(SMI)",
}
-int v3_apic_send_ipi(struct v3_vm_info * vm, struct vm_device * dev,
- struct v3_gen_ipi * ipi) {
- struct apic_dev_state * apic_dev = (struct apic_dev_state *)(dev->private_data);
+int v3_apic_send_ipi(struct v3_vm_info * vm, struct v3_gen_ipi * ipi, void * dev_data) {
+ struct apic_dev_state * apic_dev = (struct apic_dev_state *)dev_data;
struct int_cmd_reg tmp_icr;
// zero out all the fields
}
-int v3_apic_raise_intr(struct v3_vm_info * vm, struct vm_device * dev,
- uint32_t irq, uint32_t dst) {
- struct apic_dev_state * apic_dev = (struct apic_dev_state *)(dev->private_data);
+int v3_apic_raise_intr(struct v3_vm_info * vm, uint32_t irq, uint32_t dst, void * dev_data) {
+ struct apic_dev_state * apic_dev = (struct apic_dev_state *)(dev_data);
struct apic_state * apic = &(apic_dev->apics[dst]);
PrintDebug("apic %u core ?: raising interrupt IRQ %u (dst = %u).\n", apic->lapic_id.val, irq, dst);
static struct v3_device_ops dev_ops = {
.free = apic_free,
- .reset = NULL,
- .start = NULL,
- .stop = NULL,
};
static struct v3_device_ops dev_ops = {
.free = model_free,
- .reset = NULL,
- .start = NULL,
- .stop = NULL,
};
static struct v3_device_ops dev_ops = {
.free = disk_free,
- .reset = NULL,
- .start = NULL,
- .stop = NULL,
};
static struct v3_device_ops dev_ops = {
.free = i440_free,
- .reset = NULL,
- .start = NULL,
- .stop = NULL,
+
};
pci_dev = v3_pci_register_device(state->pci, PCI_STD_DEVICE,
0, 0, 0, "i440FX", bars,
- NULL, NULL, NULL, dev);
+ NULL, NULL, NULL, state);
if (!pci_dev) {
v3_detach_device(dev);
#ifdef CONFIG_DEBUG_IDE
-static void print_prd_table(struct vm_device * dev, struct ide_channel * channel) {
+static void print_prd_table(struct ide_internal * ide, struct ide_channel * channel) {
struct ide_dma_prd prd_entry;
int index = 0;
uint32_t prd_entry_addr = channel->dma_prd_addr + (sizeof(struct ide_dma_prd) * index);
int ret;
- ret = v3_read_gpa_memory(&(dev->vm->cores[0]), prd_entry_addr, sizeof(struct ide_dma_prd), (void *)&prd_entry);
+ ret = v3_read_gpa_memory(&(ide->vm->cores[0]), prd_entry_addr, sizeof(struct ide_dma_prd), (void *)&prd_entry);
if (ret != sizeof(struct ide_dma_prd)) {
PrintError("Could not read PRD\n");
static int pci_config_update(uint_t reg_num, void * src, uint_t length, void * private_data) {
PrintDebug("PCI Config Update\n");
- /* struct vm_device * dev = (struct vm_device *)private_data;
- struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
+ /*
+ struct ide_internal * ide = (struct ide_internal *)(private_data);
PrintDebug("\t\tInterupt register (Dev=%s), irq=%d\n", ide->ide_pci->name, ide->ide_pci->config_header.intr_line);
*/
bars[4].io_read = read_dma_port;
bars[4].io_write = write_dma_port;
- bars[4].private_data = dev;
+ bars[4].private_data = ide;
pci_dev = v3_pci_register_device(ide->pci_bus, PCI_STD_DEVICE, 0, sb_pci->dev_num, 1,
"PIIX3_IDE", bars,
- pci_config_update, NULL, NULL, dev);
+ pci_config_update, NULL, NULL, ide);
if (pci_dev == NULL) {
PrintError("Failed to register IDE BUS %d with PCI\n", i);
-int v3_ide_get_geometry(struct vm_device * ide_dev, int channel_num, int drive_num,
+int v3_ide_get_geometry(void * ide_data, int channel_num, int drive_num,
uint32_t * cylinders, uint32_t * heads, uint32_t * sectors) {
- struct ide_internal * ide = (struct ide_internal *)(ide_dev->private_data);
+ struct ide_internal * ide = ide_data;
struct ide_channel * channel = &(ide->channels[channel_num]);
struct ide_drive * drive = &(channel->drives[drive_num]);
struct redir_tbl_entry redir_tbl[24];
- struct vm_device * apic_dev;
+ void * apic_dev_data;
};
static int ioapic_read(struct guest_info * core, addr_t guest_addr, void * dst, uint_t length, void * priv_data) {
- struct vm_device * dev = (struct vm_device *)priv_data;
- struct io_apic_state * ioapic = (struct io_apic_state *)(dev->private_data);
+ struct io_apic_state * ioapic = (struct io_apic_state *)(priv_data);
uint32_t reg_tgt = guest_addr - ioapic->base_addr;
uint32_t * op_val = (uint32_t *)dst;
static int ioapic_write(struct guest_info * core, addr_t guest_addr, void * src, uint_t length, void * priv_data) {
- struct vm_device * dev = (struct vm_device *)priv_data;
- struct io_apic_state * ioapic = (struct io_apic_state *)(dev->private_data);
+ struct io_apic_state * ioapic = (struct io_apic_state *)(priv_data);
uint32_t reg_tgt = guest_addr - ioapic->base_addr;
uint32_t op_val = *(uint32_t *)src;
static int ioapic_raise_irq(struct v3_vm_info * vm, void * private_data, int irq) {
- struct vm_device * dev = (struct vm_device *)private_data;
- struct io_apic_state * ioapic = (struct io_apic_state *)(dev->private_data);
+ struct io_apic_state * ioapic = (struct io_apic_state *)(private_data);
struct redir_tbl_entry * irq_entry = NULL;
if (irq > 24) {
ipi.dst_shorthand = 0;
// Need to add destination argument here...
- if (v3_apic_send_ipi(vm, ioapic->apic_dev, &ipi) == -1) {
+ if (v3_apic_send_ipi(vm, &ipi, ioapic->apic_dev_data) == -1) {
PrintError("Error sending IPI to apic %d\n", ipi.dst);
return -1;
}
static struct v3_device_ops dev_ops = {
.free = io_apic_free,
- .reset = NULL,
- .start = NULL,
- .stop = NULL,
+
};
struct io_apic_state * ioapic = (struct io_apic_state *)V3_Malloc(sizeof(struct io_apic_state));
- ioapic->apic_dev = apic_dev;
+ ioapic->apic_dev_data = apic_dev;
struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, ioapic);
}
- v3_register_intr_router(vm, &router_ops, dev);
+ v3_register_intr_router(vm, &router_ops, ioapic);
- init_ioapic_state(ioapic,vm->num_cores);
+ init_ioapic_state(ioapic, vm->num_cores);
v3_hook_full_mem(vm, V3_MEM_CORE_ANY, ioapic->base_addr, ioapic->base_addr + PAGE_SIZE_4KB,
- ioapic_read, ioapic_write, dev);
+ ioapic_read, ioapic_write, ioapic);
return 0;
}
return -1;
}
-static int virtio_reset(struct vm_device * dev) {
- struct virtio_balloon_state * virtio = (struct virtio_balloon_state *)dev->private_data;
+static int virtio_reset(struct virtio_balloon_state * virtio) {
memset(virtio->queue, 0, sizeof(struct virtio_queue) * 2);
}
-static int handle_kick(struct guest_info * core, struct vm_device * dev) {
- struct virtio_balloon_state * virtio = (struct virtio_balloon_state *)dev->private_data;
+static int handle_kick(struct guest_info * core, struct virtio_balloon_state * virtio) {
struct virtio_queue * q = virtio->cur_queue;
PrintDebug("VIRTIO BALLOON KICK: cur_index=%d (mod=%d), avail_index=%d\n",
}
/*
- if (handle_balloon_op(dev, tmp_desc, buf_desc, status_desc) == -1) {
+ if (handle_balloon_op(virtio, tmp_desc, buf_desc, status_desc) == -1) {
PrintError("Error handling balloon operation\n");
return -1;
}
}
static int virtio_io_write(struct guest_info * core, uint16_t port, void * src, uint_t length, void * private_data) {
- struct vm_device * dev = (struct vm_device *)private_data;
- struct virtio_balloon_state * virtio = (struct virtio_balloon_state *)dev->private_data;
+ struct virtio_balloon_state * virtio = (struct virtio_balloon_state *)private_data;
int port_idx = port % virtio->io_range_size;
break;
case VRING_Q_NOTIFY_PORT:
PrintDebug("Handling Kick\n");
- if (handle_kick(core, dev) == -1) {
+ if (handle_kick(core, virtio) == -1) {
PrintError("Could not handle Balloon Notification\n");
return -1;
}
if (virtio->virtio_cfg.status == 0) {
PrintDebug("Resetting device\n");
- virtio_reset(dev);
+ virtio_reset(virtio);
}
break;
static int virtio_io_read(struct guest_info * core, uint16_t port, void * dst, uint_t length, void * private_data) {
- struct vm_device * dev = (struct vm_device *)private_data;
- struct virtio_balloon_state * virtio = (struct virtio_balloon_state *)dev->private_data;
+ struct virtio_balloon_state * virtio = (struct virtio_balloon_state *)private_data;
int port_idx = port % virtio->io_range_size;
static struct v3_device_ops dev_ops = {
.free = virtio_free,
- .reset = NULL,
- .start = NULL,
- .stop = NULL,
-};
+};
-static int set_size(struct vm_device * dev, addr_t size) {
- struct virtio_balloon_state * virtio = (struct virtio_balloon_state *)dev->private_data;
+static int set_size(struct virtio_balloon_state * virtio, addr_t size) {
virtio->balloon_cfg.requested_pages = size / PAGE_SIZE; // number of pages
PrintDebug("Requesting %d pages\n", virtio->balloon_cfg.requested_pages);
static int handle_hcall(struct guest_info * info, uint_t hcall_id, void * priv_data) {
- struct vm_device * dev = (struct vm_device *)priv_data;
+ struct virtio_balloon_state * virtio = (struct virtio_balloon_state *)priv_data;
int tgt_size = info->vm_regs.rcx;
- return set_size(dev, tgt_size);
+ return set_size(virtio, tgt_size);
}
static int handle_query_hcall(struct guest_info * info, uint_t hcall_id, void * priv_data) {
- struct vm_device * dev = (struct vm_device *)priv_data;
- struct virtio_balloon_state * virtio = (struct virtio_balloon_state *)dev->private_data;
+ struct virtio_balloon_state * virtio = (struct virtio_balloon_state *)priv_data;
info->vm_regs.rcx = virtio->balloon_cfg.requested_pages;
info->vm_regs.rdx = virtio->balloon_cfg.allocated_pages;
bars[0].io_read = virtio_io_read;
bars[0].io_write = virtio_io_write;
- bars[0].private_data = dev;
+ bars[0].private_data = virtio_state;
pci_dev = v3_pci_register_device(pci_bus, PCI_STD_DEVICE,
0, PCI_AUTO_DEV_NUM, 0,
"LNX_VIRTIO_BALLOON", bars,
- NULL, NULL, NULL, dev);
+ NULL, NULL, NULL, virtio_state);
if (!pci_dev) {
PrintError("Could not register PCI Device\n");
virtio_state->pci_bus = pci_bus;
}
- virtio_reset(dev);
+ virtio_reset(virtio_state);
- v3_register_hypercall(vm, BALLOON_START_HCALL, handle_hcall, dev);
- v3_register_hypercall(vm, BALLOON_QUERY_HCALL, handle_query_hcall, dev);
+ v3_register_hypercall(vm, BALLOON_START_HCALL, handle_hcall, virtio_state);
+ v3_register_hypercall(vm, BALLOON_QUERY_HCALL, handle_query_hcall, virtio_state);
return 0;
}
}
-static int virtio_reset(struct vm_device * dev) {
- struct virtio_dev_state * dev_state = (struct virtio_dev_state *)(dev->private_data);
- struct virtio_blk_state * blk_state = NULL;
- list_for_each_entry(blk_state, &(dev_state->dev_list), dev_link) {
- blk_reset(blk_state);
- }
-
- return 0;
-}
static int handle_read_op(struct virtio_blk_state * blk_state, uint8_t * buf, uint64_t * sector, uint64_t len) {
int ret = -1;
static struct v3_device_ops dev_ops = {
.free = virtio_free,
- .reset = virtio_reset,
- .start = NULL,
- .stop = NULL,
+
};
return -ERR_VIRTIO_OTHER;
}
- return virtio->net_ops->send(buf, len, virtio->backend_data, NULL);
+ return virtio->net_ops->send(buf, len, virtio->backend_data);
}
static struct v3_device_ops dev_ops = {
.free = virtio_free,
- .reset = NULL,
- .start = NULL,
- .stop = NULL,
};
static struct v3_device_ops dev_ops = {
.free = NULL,
- .reset = NULL,
- .start = NULL,
- .stop = NULL,
};
bars[0].io_read = virtio_io_read;
bars[0].io_write = virtio_io_write;
- bars[0].private_data = dev;
+ bars[0].private_data = virtio_state;
pci_dev = v3_pci_register_device(pci_bus, PCI_STD_DEVICE,
0, PCI_AUTO_DEV_NUM, 0,
"LNX_VIRTIO_SYM", bars,
- NULL, NULL, NULL, dev);
+ NULL, NULL, NULL, virtio_state);
if (!pci_dev) {
PrintError("Could not register PCI Device\n");
}
+static int virtio_free(struct vm_device * dev)
+{
+
+ return 0;
+}
static struct v3_device_ops dev_ops = {
- .free = NULL,
- .reset = NULL,
- .start = NULL,
- .stop = NULL,
+ .free = virtio_free,
};
static struct v3_device_ops dev_ops = {
.free = disk_free,
- .reset = NULL,
- .start = NULL,
- .stop = NULL,
};
};
static int bridge_send(uint8_t * buf, uint32_t len,
- void * private_data, struct vm_device *dev){
+ void * private_data) {
//struct nic_bridge_state *bridge = (struct nic_bridge_state *)private_data;
#ifdef CONFIG_DEBUG_NIC_BRIDGE
static int packet_input(struct v3_vm_info * vm,
struct v3_packet_event * evt,
void * private_data) {
- struct nic_bridge_state *bridge = (struct nic_bridge_state *)private_data;
+ struct nic_bridge_state * bridge = (struct nic_bridge_state *)private_data;
PrintDebug("NIC_BRIDGE: Incoming packet size: %d\n", evt->size);
return bridge->net_ops.recv(evt->pkt,
- evt->size,
- bridge->net_ops.frontend_data);
+ evt->size,
+ bridge->net_ops.frontend_data);
}
static struct v3_device_ops dev_ops = {
.free = vnet_nic_free,
- .reset = NULL,
- .start = NULL,
- .stop = NULL,
+
};
static int vnet_nic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
PrintDebug("NIC-Bridge: Connect %s to frontend %s\n",
dev_id, v3_cfg_val(frontend_cfg, "tag"));
- v3_hook_host_event(vm, HOST_PACKET_EVT, V3_HOST_EVENT_HANDLER(packet_input), dev);
+ v3_hook_host_event(vm, HOST_PACKET_EVT, V3_HOST_EVENT_HANDLER(packet_input), bridge);
return 0;
}
uint8_t dev_map[MAX_BUS_DEVICES / 8];
- int (*raise_pci_irq)(struct vm_device * dev, struct pci_device * pci_dev);
- int (*lower_pci_irq)(struct vm_device * dev, struct pci_device * pci_dev);
- struct vm_device * irq_bridge_dev;
+ int (*raise_pci_irq)(struct pci_device * pci_dev, void * dev_data);
+ int (*lower_pci_irq)(struct pci_device * pci_dev, void * dev_data);
+ void * irq_dev_data;
};
int v3_pci_set_irq_bridge(struct vm_device * pci_bus, int bus_num,
- int (*raise_pci_irq)(struct vm_device * dev, struct pci_device * pci_dev),
- int (*lower_pci_irq)(struct vm_device * dev, struct pci_device * pci_dev),
- struct vm_device * bridge_dev) {
+ int (*raise_pci_irq)(struct pci_device * pci_dev, void * dev_data),
+ int (*lower_pci_irq)(struct pci_device * pci_dev, void * dev_data),
+ void * priv_data) {
struct pci_internal * pci_state = (struct pci_internal *)pci_bus->private_data;
pci_state->bus_list[bus_num].raise_pci_irq = raise_pci_irq;
pci_state->bus_list[bus_num].lower_pci_irq = lower_pci_irq;
- pci_state->bus_list[bus_num].irq_bridge_dev = bridge_dev;
+ pci_state->bus_list[bus_num].irq_dev_data = priv_data;
return 0;
}
struct pci_internal * pci_state = (struct pci_internal *)pci_bus->private_data;
struct pci_bus * bus = &(pci_state->bus_list[bus_num]);
- return bus->raise_pci_irq(bus->irq_bridge_dev, dev);
+ return bus->raise_pci_irq(bus->irq_dev_data, dev);
}
int v3_pci_lower_irq(struct vm_device * pci_bus, int bus_num, struct pci_device * dev) {
struct pci_internal * pci_state = (struct pci_internal *)pci_bus->private_data;
struct pci_bus * bus = &(pci_state->bus_list[bus_num]);
- return bus->lower_pci_irq(bus->irq_bridge_dev, dev);
+ return bus->lower_pci_irq(bus->irq_dev_data, dev);
}
// if dev_num == -1, auto assign
static struct v3_device_ops dev_ops = {
.free = NULL,
- .reset = NULL,
- .start = NULL,
- .stop = NULL,
};
-static int reset_piix3(struct vm_device * dev) {
- struct v3_southbridge * piix3 = (struct v3_southbridge *)(dev->private_data);
+static int reset_piix3(struct v3_southbridge * piix3) {
struct pci_device * pci_dev = piix3->southbridge_pci;
struct piix3_config_space * piix3_cfg = (struct piix3_config_space *)(pci_dev->config_data);
//irq is pirq_rc[intr_pin + pci_dev_num - 1] & 0x3
-static int raise_pci_irq(struct vm_device * dev, struct pci_device * pci_dev) {
- struct v3_southbridge * piix3 = (struct v3_southbridge *)(dev->private_data);
+static int raise_pci_irq(struct pci_device * pci_dev, void * dev_data) {
+ struct v3_southbridge * piix3 = dev_data;
struct pci_device * piix3_pci = piix3->southbridge_pci;
struct piix3_config_space * piix3_cfg = (struct piix3_config_space *)(piix3_pci->config_data);
int intr_pin = pci_dev->config_header.intr_pin - 1;
// PrintError("Raising PCI IRQ %d\n", piix3_cfg->pirq_rc[irq_index]);
- v3_raise_irq(dev->vm, piix3_cfg->pirq_rc[irq_index]);
+ v3_raise_irq(piix3->vm, piix3_cfg->pirq_rc[irq_index]);
return 0;
}
-static int lower_pci_irq(struct vm_device * dev, struct pci_device * pci_dev) {
- struct v3_southbridge * piix3 = (struct v3_southbridge *)(dev->private_data);
+static int lower_pci_irq(struct pci_device * pci_dev, void * dev_data) {
+ struct v3_southbridge * piix3 = dev_data;
struct pci_device * piix3_pci = piix3->southbridge_pci;
struct piix3_config_space * piix3_cfg = (struct piix3_config_space *)(piix3_pci->config_data);
int intr_pin = pci_dev->config_header.intr_pin - 1;
// PrintError("Lowering PCI IRQ %d\n", piix3_cfg->pirq_rc[irq_index]);
- v3_lower_irq(dev->vm, piix3_cfg->pirq_rc[irq_index]);
+ v3_lower_irq(piix3->vm, piix3_cfg->pirq_rc[irq_index]);
return 0;
}
static struct v3_device_ops dev_ops = {
.free = piix_free,
- .reset = reset_piix3,
- .start = NULL,
- .stop = NULL,
};
-static int setup_pci(struct vm_device * dev) {
- struct v3_southbridge * piix3 = (struct v3_southbridge *)(dev->private_data);
+static int setup_pci(struct v3_southbridge * piix3) {
struct pci_device * pci_dev = NULL;
struct v3_pci_bar bars[6];
int i;
pci_dev = v3_pci_register_device(piix3->pci_bus, PCI_MULTIFUNCTION,
bus_num, -1, 0,
"PIIX3", bars,
- NULL, NULL, NULL, dev);
+ NULL, NULL, NULL, piix3);
if (pci_dev == NULL) {
PrintError("Could not register PCI Device for PIIX3\n");
return -1;
piix3->southbridge_pci = pci_dev;
- v3_pci_set_irq_bridge(piix3->pci_bus, bus_num, raise_pci_irq, lower_pci_irq, dev);
+ v3_pci_set_irq_bridge(piix3->pci_bus, bus_num, raise_pci_irq, lower_pci_irq, piix3);
- reset_piix3(dev);
+ reset_piix3(piix3);
return 0;
}
PrintDebug("Created PIIX3\n");
- return setup_pci(dev);
+ return setup_pci(piix3);
}
static struct v3_device_ops dev_ops = {
.free = disk_free,
- .reset = NULL,
- .start = NULL,
- .stop = NULL,
};
return length;
}
-static int serial_deinit(struct vm_device * dev) {
+static int serial_free(struct vm_device * dev) {
return 0;
}
static struct v3_device_ops dev_ops = {
- //.init = serial_init,
- .free = serial_deinit,
- .reset = NULL,
+ .free = serial_free,
};
#include <palacios/vmm_socket.h>
#include <devices/console.h>
-#if 0
-#include <devices/telnet_cons.h>
-#endif
+
#define NUM_ROWS 25
#define NUM_COLS 80
v3_lock_t cons_lock;
+ v3_vm_info * vm;
+
struct vm_device * frontend_dev;
};
-static int deliver_scan_code(struct vm_device * dev, struct key_code * key) {
+static int deliver_scan_code(struct cons_state * state, struct key_code * key) {
struct v3_keyboard_event key_event;
struct v3_keyboard_event key_shift;
uint_t cap = key->capital;
key_shift.status = 0;
key_shift.scan_code = (uint8_t)0x2A;
- if (v3_deliver_keyboard_event(dev->vm, &key_shift) == -1) {
+ if (v3_deliver_keyboard_event(state->vm, &key_shift) == -1) {
PrintError("Video: Error delivering key event\n");
return -1;
}
}
// Press
- if (v3_deliver_keyboard_event(dev->vm, &key_event) == -1) {
+ if (v3_deliver_keyboard_event(state->vm, &key_event) == -1) {
PrintError("Video: Error delivering key event\n");
return -1;
}
// Release
key_event.scan_code = key_event.scan_code | 0x80;
- if (v3_deliver_keyboard_event(dev->vm, &key_event) == -1) {
+ if (v3_deliver_keyboard_event(state->vm, &key_event) == -1) {
PrintError("Video: Error delivering key event\n");
return -1;
}
if (cap) {
key_shift.scan_code = 0x2A | 0x80;
- if (v3_deliver_keyboard_event(dev->vm, &key_shift) == -1) {
+ if (v3_deliver_keyboard_event(state->vm, &key_shift) == -1) {
PrintError("Video: Error delivering key event\n");
return -1;
}
} while (0)
-static int send_update(struct vm_device * dev, uint8_t x, uint8_t y, uint8_t attrib, uint8_t val) {
- struct cons_state * state = (struct cons_state *)dev->private_data;
+static int send_update(struct cons_state * state, uint8_t x, uint8_t y, uint8_t attrib, uint8_t val) {
uint8_t fg_color = fg_color_map[(attrib & 0x0f) % 16];
uint8_t bg_color = bg_color_map[(attrib & 0xf0) % 16];
uint8_t buf[32];
static int cursor_update(uint_t x, uint_t y, void * private_data) {
- struct vm_device * dev = (struct vm_device *)private_data;
- struct cons_state * state = (struct cons_state *)dev->private_data;
+ struct cons_state * state = (struct cons_state *)private_data;
uint8_t buf[16];
int ret = 0;
addr_t irq_state = 0;
static int screen_update(uint_t x, uint_t y, uint_t length, void * private_data) {
- struct vm_device * dev = (struct vm_device *)private_data;
- struct cons_state * state = (struct cons_state *)dev->private_data;
+ struct cons_state * state = (struct cons_state *)private_data;
uint_t offset = (x * BYTES_PER_COL) + (y * BYTES_PER_ROW);
uint8_t fb_buf[length];
int i = 0;
irq_state = v3_lock_irqsave(state->cons_lock);
- if (send_update(dev, cur_x, cur_y, col[1], col[0]) == -1) {
+ if (send_update(state, cur_x, cur_y, col[1], col[0]) == -1) {
PrintError("Could not send attribute to telnet session\n");
ret = -1;
break;
}
static int scroll(int rows, void * private_data) {
- struct vm_device * dev = (struct vm_device *)private_data;
- struct cons_state * state = (struct cons_state *)dev->private_data;
+ struct cons_state * state = (struct cons_state *)private_data;
addr_t irq_state = 0;
int ret = 0;
.scroll = scroll,
};
+static int cons_free(struct vm_device * dev) {
+ return -1;
+}
+
static struct v3_device_ops dev_ops = {
- .free = NULL,
- .reset = NULL,
- .start = NULL,
- .stop = NULL,
+ .free = cons_free,
};
-static int key_handler(struct vm_device * dev, uint8_t ascii) {
- struct cons_state * state = (struct cons_state *)dev->private_data;
-
+static int key_handler( struct cons_state * state, uint8_t ascii) {
PrintDebug("Character recieved: 0x%x\n", ascii);
// printable
if (ascii < 0x80) {
const struct key_code * key = &(ascii_to_key_code[ascii]);
- if (deliver_scan_code(dev, (struct key_code *)key) == -1) {
+ if (deliver_scan_code(state, (struct key_code *)key) == -1) {
PrintError("Could not deliver scan code to vm\n");
return -1;
}
if (esc_seq[1] == 'A') { // UP ARROW
struct key_code up = { 0x48, 0 };
- deliver_scan_code(dev, &up);
+ deliver_scan_code(state, &up);
} else if (esc_seq[1] == 'B') { // DOWN ARROW
struct key_code down = { 0x50, 0 };
- deliver_scan_code(dev, &down);
+ deliver_scan_code(state, &down);
} else if (esc_seq[1] == 'C') { // RIGHT ARROW
struct key_code right = { 0x4D, 0 };
- deliver_scan_code(dev, &right);
+ deliver_scan_code(state, &right);
} else if (esc_seq[1] == 'D') { // LEFT ARROW
struct key_code left = { 0x4B, 0 };
- deliver_scan_code(dev, &left);
+ deliver_scan_code(state, &left);
}
} else {
PrintError("Invalid character received from network (%c) (code=%d)\n",
}
static int cons_server(void * arg) {
- struct vm_device * dev = (struct vm_device *)arg;
- struct cons_state * state = (struct cons_state *)dev->private_data;
+ struct cons_state * state = (struct cons_state *)arg;
state->server_fd = V3_Create_TCP_Socket();
PrintDebug("Accepted Telnet Console connection\n");
state->connected = 1;
- screen_update(0, 0, SCREEN_SIZE, dev);
+ screen_update(0, 0, SCREEN_SIZE, state);
while (1) {
recv = recv_all(state->client_fd, &ascii_code, sizeof(ascii_code));
break;
}
- if (key_handler(dev, ascii_code) == -1) {
+ if (key_handler(state, ascii_code) == -1) {
PrintError("Error in key handler\n");
break;
}
struct vm_device * frontend = v3_find_dev(vm, v3_cfg_val(frontend_cfg, "tag"));
char * dev_id = v3_cfg_val(cfg, "ID");
-
+ state->vm = vm;
state->server_fd = 0;
state->client_fd = 0;
state->frontend_dev = frontend;
}
- v3_console_register_cga(frontend, &cons_ops, dev);
+ v3_console_register_cga(frontend, &cons_ops, state);
- V3_CREATE_THREAD(cons_server, dev, "Telnet Console Network Server");
+ V3_CREATE_THREAD(cons_server, state, "Telnet Console Network Server");
return 0;
}
static struct v3_device_ops dev_ops = {
.free = blk_free,
- .reset = NULL,
- .start = NULL,
- .stop = NULL,
+
};
/* called by frontend, send pkt to VNET */
static int vnet_nic_send(uint8_t * buf, uint32_t len,
- void * private_data,
- struct vm_device * dest_dev){
- struct vnet_nic_state *vnetnic = (struct vnet_nic_state *)private_data;
+ void * private_data) {
+ struct vnet_nic_state * vnetnic = (struct vnet_nic_state *)private_data;
struct v3_vnet_pkt pkt;
pkt.size = len;
static struct v3_device_ops dev_ops = {
.free = vnet_nic_free,
- .reset = NULL,
- .start = NULL,
- .stop = NULL,
+
};
static struct v3_vnet_dev_ops vnet_dev_ops = {
INIT_LIST_HEAD(&(mgr->blk_list));
INIT_LIST_HEAD(&(mgr->net_list));
INIT_LIST_HEAD(&(mgr->char_list));
- INIT_LIST_HEAD(&(mgr->console_list));
+ INIT_LIST_HEAD(&(mgr->cons_list));
mgr->blk_table = v3_create_htable(0, dev_hash_fn, dev_eq_fn);
mgr->net_table = v3_create_htable(0, dev_hash_fn, dev_eq_fn);
mgr->char_table = v3_create_htable(0, dev_hash_fn, dev_eq_fn);
- mgr->console_table = v3_create_htable(0, dev_hash_fn, dev_eq_fn);
+ mgr->cons_table = v3_create_htable(0, dev_hash_fn, dev_eq_fn);
return 0;
}
v3_free_htable(mgr->blk_table, 0, 0);
v3_free_htable(mgr->net_table, 0, 0);
v3_free_htable(mgr->char_table, 0, 0);
- v3_free_htable(mgr->console_table, 0, 0);
+ v3_free_htable(mgr->cons_table, 0, 0);
v3_free_htable(mgr->dev_table, 0, 0);
}
+struct cons_frontend {
+ int (*connect)(struct v3_vm_info * vm,
+ void * frontend_data,
+ struct v3_dev_console_ops * ops,
+ v3_cfg_tree_t * cfg,
+ void * priv_data);
+
+
+ struct list_head cons_node;
+
+ void * priv_data;
+};
+
+int v3_dev_add_console_frontend(struct v3_vm_info * vm,
+ char * name,
+ int (*connect)(struct v3_vm_info * vm,
+ void * frontend_data,
+ struct v3_dev_console_ops * ops,
+ v3_cfg_tree_t * cfg,
+ void * private_data),
+ void * priv_data)
+{
+ struct cons_frontend * frontend = NULL;
+
+ frontend = (struct cons_frontend *)V3_Malloc(sizeof(struct cons_frontend));
+ memset(frontend, 0, sizeof(struct cons_frontend));
+
+ frontend->connect = connect;
+ frontend->priv_data = priv_data;
+
+ list_add(&(frontend->cons_node), &(vm->dev_mgr.cons_list));
+ v3_htable_insert(vm->dev_mgr.cons_table, (addr_t)(name), (addr_t)frontend);
+
+ return 0;
+}
+
+
+int v3_dev_connect_console(struct v3_vm_info * vm,
+ char * frontend_name,
+ struct v3_dev_console_ops * ops,
+ v3_cfg_tree_t * cfg,
+ void * private_data)
+{
+ struct cons_frontend * frontend = NULL;
+
+ frontend = (struct cons_frontend *)v3_htable_search(vm->dev_mgr.cons_table,
+ (addr_t)frontend_name);
+
+ if (frontend == NULL) {
+ PrintError("Could not find frontend console device %s\n", frontend_name);
+ return 0;
+ }
+
+ if (frontend->connect(vm, frontend->priv_data, ops, cfg, private_data) == -1) {
+ PrintError("Error connecting to console frontend %s\n", frontend_name);
+ return -1;
+ }
+
+ return 0;
+}
+
struct char_frontend {
int (*connect)(struct v3_vm_info * vm,
void * frontend_data,
void * priv_data;
};
-
-
int v3_dev_add_char_frontend(struct v3_vm_info * vm,
char * name,
int (*connect)(struct v3_vm_info * vm,