vmm: Increase the vmthread stack size
[akaros.git] / user / vmm / ioapic.c
index 5f8fb2a..bd0ed0e 100644 (file)
 #include <vmm/virtio_mmio.h>
 #include <vmm/virtio_ids.h>
 #include <vmm/virtio_config.h>
+#include <vmm/sched.h>
 
 #define IOAPIC_CONFIG 0x100
 #define IOAPIC_NUM_PINS 24
 
-int debug_ioapic = 1;
+int debug_ioapic;
 int apic_id_mask = 0xf0;
 
 #define DPRINTF(fmt, ...) \
@@ -46,12 +47,12 @@ struct ioapic {
 
 static struct ioapic ioapic[1];
 
-static uint32_t ioapic_read(int ix, uint64_t offset)
+static uint32_t ioapic_read(struct guest_thread *vm_thread, int ix,
+                            uint64_t offset)
 {
        uint32_t ret = (uint32_t)-1;
        uint32_t reg = ioapic[ix].reg;
 
-
        if (offset == 0) {
                DPRINTF("ioapic_read ix %x return 0x%x\n", ix, reg);
                return reg;
@@ -84,10 +85,13 @@ static uint32_t ioapic_read(int ix, uint64_t offset)
        return 0;
 }
 
-static void ioapic_write(int ix, uint64_t offset, uint32_t value)
+static void ioapic_write(struct guest_thread *vm_thread, int ix,
+                         uint64_t offset, uint32_t value)
 {
        uint32_t ret;
        uint32_t reg = ioapic[ix].reg;
+       struct virtual_machine *vm = gth_to_vm(vm_thread);
+       uint32_t irqreg;
 
        if (offset == 0) {
                DPRINTF("ioapic_write ix %x set reg 0x%x\n", ix, value);
@@ -95,6 +99,30 @@ static void ioapic_write(int ix, uint64_t offset, uint32_t value)
                return;
        }
 
+       for (int i = 0; i < VIRTIO_MMIO_MAX_NUM_DEV; i++) {
+               if (vm->virtio_mmio_devices[i] == NULL)
+                       continue;
+
+               /* The first IRQ register starts at 0x10, and there are two 32-bit
+                * registers for each IRQ. The first 8 bits of the value assigned to
+                * 'reg' is the interrupt vector. */
+               irqreg = (vm->virtio_mmio_devices[i]->irq) * 2 + 0x10;
+               if (reg == irqreg && (value & 0xff) != 0) {
+                       vm->virtio_mmio_devices[i]->vec = value & 0xff;
+                       DPRINTF("irq vector for irq number %d is: %lx\n",
+                                vm->virtio_mmio_devices[i]->irq, value & 0xff);
+               } else if (reg == irqreg + 1) {
+                       vm->virtio_mmio_devices[i]->dest = value >> 24;
+                       if (value >> 24 == 0xff)
+                               vm->virtio_mmio_devices[i]->dest = 0xffffffff;
+
+                       DPRINTF("high value for irq number %d is: %lx\n",
+                                vm->virtio_mmio_devices[i]->irq, value);
+                       DPRINTF("irq destination for irq number %d is: %lx\n",
+                                vm->virtio_mmio_devices[i]->irq, value >> 24);
+               }
+       }
+
        switch (reg) {
        case 0:
                DPRINTF("IOAPIC_WRITE: Set %d ID to %d\n", ix, value);
@@ -115,9 +143,10 @@ static void ioapic_write(int ix, uint64_t offset, uint32_t value)
 
 }
 
-int do_ioapic(struct vmctl *v, uint64_t gpa, int destreg, uint64_t *regp, int store)
+int do_ioapic(struct guest_thread *vm_thread, uint64_t gpa, int destreg,
+              uint64_t *regp, int store)
 {
-       // TODO: compute an index for the ioapic array. 
+       /* TODO(ganshun): compute an index for the ioapic array. */
        int ix = 0;
        uint32_t offset = gpa & 0xfffff;
        /* basic sanity tests. */
@@ -129,9 +158,9 @@ int do_ioapic(struct vmctl *v, uint64_t gpa, int destreg, uint64_t *regp, int st
        }
 
        if (store) {
-               ioapic_write(ix, offset, *regp);
+               ioapic_write(vm_thread, ix, offset, *regp);
        } else {
-               *regp = ioapic_read(ix, offset);
+               *regp = ioapic_read(vm_thread, ix, offset);
        }
 
 }