Browse Source

kernel: fixup PCI irq mapping on vmware?

K. Lange 2 years ago
parent
commit
06c3fc3db5
1 changed files with 15 additions and 3 deletions
  1. 15 3
      kernel/devices/pci.c

+ 15 - 3
kernel/devices/pci.c

@@ -164,6 +164,9 @@ void pci_remap(void) {
 	if (pci_isa) {
 		for (int i = 0; i < 4; ++i) {
 			pci_remaps[i] = pci_read_field(pci_isa, 0x60+i, 1);
+			if (pci_remaps[i] == 0x80) {
+				pci_remaps[i] = 10 + (i%1);
+			}
 		}
 		uint32_t out = 0;
 		memcpy(&out, &pci_remaps, 4);
@@ -183,14 +186,23 @@ int pci_get_interrupt(uint32_t device) {
 		int pirq = (irq_pin + pci_extract_slot(device) - 2) % 4;
 		int int_line = pci_read_field(device, PCI_INTERRUPT_LINE, 1);
 		debug_print(ERROR, "slot is %d, irq pin is %d, so pirq is %d and that maps to %d? int_line=%d", pci_extract_slot(device), irq_pin, pirq, pci_remaps[pirq], int_line);
-		if (pci_remaps[pirq] == 0x80) {
-			debug_print(ERROR, "not mapped, remapping?\n");
+		for (int i = 0; i < 4; ++i) {
+			debug_print(ERROR, "  irq[%d] = %d", i, pci_remaps[i]);
+		}
+		if (pci_remaps[pirq] >= 0x80) {
+			debug_print(ERROR, "not mapped, remapping?");
+			if (int_line == 0xFF) {
+				int_line = 10;
+				pci_write_field(device, PCI_INTERRUPT_LINE, 1, int_line);
+				debug_print(ERROR, "? Just going in blind here.\n");
+			}
 			pci_remaps[pirq] = int_line;
 			uint32_t out = 0;
 			memcpy(&out, &pci_remaps, 4);
 			pci_write_field(pci_isa, 0x60, 4, out);
-			return pci_read_field(device, PCI_INTERRUPT_LINE, 1);
+			return int_line;
 		}
+		pci_write_field(device, PCI_INTERRUPT_LINE, 1, pci_remaps[pirq]);
 		return pci_remaps[pirq];
 	} else {
 		return pci_read_field(device, PCI_INTERRUPT_LINE, 1);