}
-static int pic_raise_intr(struct guest_info * info, void * private_data, int irq) {
+static int pic_raise_intr(struct v3_vm_info * vm, void * private_data, int irq) {
struct pic_internal * state = (struct pic_internal*)private_data;
if (irq == 2) {
return -1;
}
+ v3_interrupt_cpu(vm, 0);
+
return 0;
}
-static int pic_lower_intr(struct guest_info * info, void * private_data, int irq) {
+static int pic_lower_intr(struct v3_vm_info * vm, void * private_data, int irq) {
struct pic_internal * state = (struct pic_internal*)private_data;
PrintDebug("[pic_lower_intr] IRQ line %d now low\n", irq);
static struct intr_ctrl_ops intr_ops = {
.intr_pending = pic_intr_pending,
.get_intr_number = pic_get_intr_number,
- .raise_intr = pic_raise_intr,
- .begin_irq = pic_begin_irq,
- .lower_intr = pic_lower_intr,
-
+ .begin_irq = pic_begin_irq
};
+static struct intr_router_ops router_ops = {
+ .raise_intr = pic_raise_intr,
+ .lower_intr = pic_lower_intr
+};
-
-static int read_master_port1(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
+static int read_master_port1(struct guest_info * core, ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
struct pic_internal * state = (struct pic_internal*)dev->private_data;
if (length != 1) {
return 1;
}
-static int read_master_port2(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
+static int read_master_port2(struct guest_info * core, ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
struct pic_internal * state = (struct pic_internal*)dev->private_data;
if (length != 1) {
}
-static int read_slave_port1(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
+static int read_slave_port1(struct guest_info * core, ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
struct pic_internal * state = (struct pic_internal*)dev->private_data;
if (length != 1) {
return 1;
}
-static int read_slave_port2(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
+static int read_slave_port2(struct guest_info * core, ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
struct pic_internal * state = (struct pic_internal*)dev->private_data;
if (length != 1) {
}
-static int write_master_port1(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
+static int write_master_port1(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) {
struct pic_internal * state = (struct pic_internal*)dev->private_data;
uchar_t cw = *(uchar_t *)src;
return -1;
}
+ v3_clear_pending_intr(core);
+
if (IS_ICW1(cw)) {
PrintDebug("8259 PIC: Setting ICW1 = %x (wr_Master1)\n", cw);
return 1;
}
-static int write_master_port2(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
+static int write_master_port2(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) {
struct pic_internal * state = (struct pic_internal*)dev->private_data;
uchar_t cw = *(uchar_t *)src;
return -1;
}
+ v3_clear_pending_intr(core);
+
if (state->master_state == ICW2) {
struct icw1 * cw1 = (struct icw1 *)&(state->master_icw1);
PrintDebug("8259 PIC: Setting ICW2 = %x (wr_Master2)\n", cw);
state->master_icw2 = cw;
+
+
if (cw1->sngl == 0) {
state->master_state = ICW3;
} else if (cw1->ic4 == 1) {
state->master_state = READY;
}
+
+
} else if (state->master_state == ICW3) {
struct icw1 * cw1 = (struct icw1 *)&(state->master_icw1);
return 1;
}
-static int write_slave_port1(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
+static int write_slave_port1(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) {
struct pic_internal * state = (struct pic_internal*)dev->private_data;
uchar_t cw = *(uchar_t *)src;
return -1;
}
+ v3_clear_pending_intr(core);
+
if (IS_ICW1(cw)) {
PrintDebug("8259 PIC: Setting ICW1 = %x (wr_Slave1)\n", cw);
state->slave_icw1 = cw;
return 1;
}
-static int write_slave_port2(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
+static int write_slave_port2(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) {
struct pic_internal * state = (struct pic_internal*)dev->private_data;
uchar_t cw = *(uchar_t *)src;
return -1;
}
+ v3_clear_pending_intr(core);
+
+
if (state->slave_state == ICW2) {
struct icw1 * cw1 = (struct icw1 *)&(state->master_icw1);
-static int read_elcr_port(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
+static int read_elcr_port(struct guest_info * core, ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
struct pic_internal * state = (struct pic_internal*)dev->private_data;
if (length != 1) {
}
-static int write_elcr_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
+static int write_elcr_port(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) {
struct pic_internal * state = (struct pic_internal*)dev->private_data;
if (length != 1) {
-static int pic_init(struct guest_info * vm, void * cfg_data) {
+#include <palacios/vm_guest.h>
+
+static int pic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
struct pic_internal * state = NULL;
state = (struct pic_internal *)V3_Malloc(sizeof(struct pic_internal));
+ char * name = v3_cfg_val(cfg, "name");
+
+ // PIC is only usable in non-multicore environments
+ // just hardcode the core context
+ struct guest_info * core = &(vm->cores[0]);
+
V3_ASSERT(state != NULL);
- struct vm_device * dev = v3_allocate_device("8259A", &dev_ops, state);
+ struct vm_device * dev = v3_allocate_device(name, &dev_ops, state);
if (v3_attach_device(vm, dev) == -1) {
- PrintError("Could not attach device %s\n", "8259A");
+ PrintError("Could not attach device %s\n", name);
return -1;
}
- v3_register_intr_controller(vm, &intr_ops, state);
+ v3_register_intr_controller(core, &intr_ops, state);
+ v3_register_intr_router(vm, &router_ops, state);
state->master_irr = 0;
state->master_isr = 0;