Fixed ISOR problem and legacy pic patch.
authorKyle Milka <kmilka1995@gmail.com>
Fri, 1 Jul 2016 16:19:33 +0000 (09:19 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Wed, 6 Jul 2016 15:41:41 +0000 (11:41 -0400)
After removing Ron's null_legacy_pic patch from linux it is possible
to use the IOApic in the way it was intended, without resorting to the
ISOR table. IRQs are now assigned sequentially starting at 0.

Change-Id: I7f252105f0a2dfd4296648c18bc80332d048be0b
Signed-off-by: Kyle Milka <kmilka@google.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
tests/vmm/vmrunkernel.c
user/vmm/io.c
user/vmm/ioapic.c

index da704f2..bcc0c8c 100644 (file)
@@ -116,18 +116,6 @@ struct acpi_madt_interrupt_override isor[] = {
         * APIC interrupt input 2, then you would need an Interrupt Source Override
         * where the source entry is ‘0’ and the Global System Interrupt is ‘2.’
         */
-       {.header = {.type = ACPI_MADT_TYPE_INTERRUPT_OVERRIDE,
-                   .length = sizeof(struct acpi_madt_interrupt_override)},
-        .bus = 0, .source_irq = 0, .global_irq = 2, .inti_flags = 0},
-       {.header = {.type = ACPI_MADT_TYPE_INTERRUPT_OVERRIDE,
-                   .length = sizeof(struct acpi_madt_interrupt_override)},
-        .bus = 0, .source_irq = 1, .global_irq = 1, .inti_flags = 0},
-       {.header = {.type = ACPI_MADT_TYPE_INTERRUPT_OVERRIDE,
-                   .length = sizeof(struct acpi_madt_interrupt_override)},
-        .bus = 0, .source_irq = 3, .global_irq = 3, .inti_flags = 0},
-       {.header = {.type = ACPI_MADT_TYPE_INTERRUPT_OVERRIDE,
-                   .length = sizeof(struct acpi_madt_interrupt_override)},
-        .bus = 0, .source_irq = 4, .global_irq = 4, .inti_flags = 0},
 };
 
 
@@ -196,9 +184,6 @@ static void virtio_poke_guest(uint8_t vec)
 
 static struct virtio_mmio_dev cons_mmio_dev = {
        .poke_guest = virtio_poke_guest,
-       /* At the moment irq numbers cannot be below 24; this is a problem with
-        * the IOAPIC and Interrupt Source Override Structure. */
-       .irq = 26,
 };
 
 static struct virtio_console_config cons_cfg;
@@ -232,7 +217,6 @@ static struct virtio_vq_dev cons_vqdev = {
 
 static struct virtio_mmio_dev net_mmio_dev = {
        .poke_guest = virtio_poke_guest,
-       .irq = 27,
 };
 
 static struct virtio_net_config net_cfg = {
@@ -634,8 +618,14 @@ int main(int argc, char **argv)
        for (int i = 0; i < VIRTIO_MMIO_MAX_NUM_DEV; i++) {
                if (vm->virtio_mmio_devices[i] == NULL)
                        continue;
+
                /* Append all the virtio mmio base addresses. */
-               len = snprintf(cmdlinep, cmdlinesz,
+
+                       /* Since the lower number irqs are no longer being used, the irqs
+                        * can now be assigned starting from 0.
+                        */
+                       vm->virtio_mmio_devices[i]->irq = i;
+                       len = snprintf(cmdlinep, cmdlinesz,
                               " virtio_mmio.device=1K@0x%llx:%lld",
                               vm->virtio_mmio_devices[i]->addr,
                               vm->virtio_mmio_devices[i]->irq);
index f602c98..4368ed5 100644 (file)
@@ -1,4 +1,4 @@
-#include <stdio.h> 
+#include <stdio.h>
 #include <pthread.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -28,7 +28,7 @@ struct pciconfig {
 
 /* just index by devfn, i.e. 8 bits */
 struct pciconfig pcibus[] = {
-       /* linux requires that devfn 0 be a bridge. 
+       /* linux requires that devfn 0 be a bridge.
         * 00:00.0 Host bridge: Intel Corporation 440BX/ZX/DX - 82443BX/ZX/DX Host bridge (rev 01)
         */
        {
@@ -199,6 +199,19 @@ bool io(struct guest_thread *vm_thread)
                configread32(edx, &vm_tf->tf_rax);
                return true;
        }
+       /* Detects when something is written to the PIC. */
+       if (*ip8 == 0xe6) {
+               vm_tf->tf_rip += 2;
+               return true;
+       }
+       /* Detects when something is read from the PIC, so
+        * a value signifying there is no PIC is given.
+        */
+       if (*ip16 == 0x21e4) {
+               vm_tf->tf_rip += 2;
+               vm_tf->tf_rax = ~0ULL;
+               return true;
+       }
        if (*ip16 == 0xed66) {
                vm_tf->tf_rip += 2;
                //printf("configread16 ");
index 3f6d58c..507ba6f 100644 (file)
 #define IOAPIC_CONFIG 0x100
 #define IOAPIC_NUM_PINS 24
 
-/* The problem with the IOAPIC and ISOR Structure means all irq numbers
- * must be at least 24, so this is used to correct that offset. */
-#define IOAPIC_LAST_IRQ 23
-
 int debug_ioapic = 1;
 int apic_id_mask = 0xf0;
 
@@ -110,7 +106,7 @@ static void ioapic_write(struct guest_thread *vm_thread, int ix,
                /* 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 - IOAPIC_LAST_IRQ) * 2 + 0x10;
+               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",