aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHelge Deller <deller@gmx.de>2023-09-27 21:36:19 +0200
committerHelge Deller <deller@gmx.de>2023-09-27 21:36:19 +0200
commit7a54c339b768785061d0f7d35510f28b0969c8d9 (patch)
treed1d50261ff89ddf34ffc022149dd8700f854fe95
parent7c6087cd7d698135be9b899885624cb23d1e4b23 (diff)
downloadseabios-hppa-7a54c339b768785061d0f7d35510f28b0969c8d9.zip
seabios-hppa-7a54c339b768785061d0f7d35510f28b0969c8d9.tar.gz
seabios-hppa-7a54c339b768785061d0f7d35510f28b0969c8d9.tar.bz2
build IOSAPIC IRT table
-rw-r--r--src/hw/pcidevice.c5
-rw-r--r--src/hw/pcidevice.h1
-rw-r--r--src/parisc/parisc.c74
3 files changed, 53 insertions, 27 deletions
diff --git a/src/hw/pcidevice.c b/src/hw/pcidevice.c
index 8853cf7..ed3e15d 100644
--- a/src/hw/pcidevice.c
+++ b/src/hw/pcidevice.c
@@ -66,6 +66,7 @@ pci_probe_devices(void)
dev->class = classrev >> 16;
dev->prog_if = classrev >> 8;
dev->revision = classrev & 0xff;
+ dev->irq = pci_config_readb(bdf, PCI_INTERRUPT_PIN);
dev->header_type = pci_config_readb(bdf, PCI_HEADER_TYPE);
u8 v = dev->header_type & 0x7f;
if (v == PCI_HEADER_TYPE_BRIDGE || v == PCI_HEADER_TYPE_CARDBUS) {
@@ -76,8 +77,8 @@ pci_probe_devices(void)
if (secbus > MaxPCIBus)
MaxPCIBus = secbus;
}
- dprintf(4, "PCI device %pP (vd=%04x:%04x c=%04x)\n"
- , dev, dev->vendor, dev->device, dev->class);
+ dprintf(4, "PCI device %pP (vd=%04x:%04x c=%04x, irq=%d)\n"
+ , dev, dev->vendor, dev->device, dev->class, dev->irq);
}
}
dprintf(1, "Found %d PCI devices (max PCI bus is %02x)\n", count, MaxPCIBus);
diff --git a/src/hw/pcidevice.h b/src/hw/pcidevice.h
index 225d545..eb3de39 100644
--- a/src/hw/pcidevice.h
+++ b/src/hw/pcidevice.h
@@ -16,6 +16,7 @@ struct pci_device {
u8 prog_if, revision;
u8 header_type;
u8 secondary_bus;
+ u8 irq;
// Local information on device.
int have_driver;
diff --git a/src/parisc/parisc.c b/src/parisc/parisc.c
index 06a1d3c..469f40f 100644
--- a/src/parisc/parisc.c
+++ b/src/parisc/parisc.c
@@ -1555,12 +1555,6 @@ static int pdc_lan_station_id(unsigned int *arg)
return PDC_BAD_OPTION;
}
-static int pdc_pci_index(unsigned int *arg)
-{
- unsigned long option = ARG1;
- unsigned long *result = (unsigned long *)ARG2;
- /* machines with Dino don't provide this info */
- u32 *irt_table, i;
#if 0
[ 3.212566] iosapic Interrupt Routing Table (cell 0)
@@ -1577,14 +1571,44 @@ static int pdc_pci_index(unsigned int *arg)
((u32 *) p)[2],
((u32 *) p)[3]
#endif
- #define IRT_TABLE_ENTRIES 5
- #define IOSAPIC_HPA 0xfffffffffed30800ULL
- const u32 irt_table_const[2 * IRT_TABLE_ENTRIES] = {
- 0x8b10000f, 0x00000002, // erstes byte
- 0x8b10000f, 0x04000003,
- 0x8b10000d, 0x08000000,
- 0x8b10000f, 0x3c000001,
- 0x8b10000f, 0x3c000001 };
+#define IRT_TABLE_ENTRIES 24
+#define IOSAPIC_HPA 0xfffffffffed30800ULL
+static int irt_table_entries;
+static u32 irt_table[IRT_TABLE_ENTRIES * 16/sizeof(u32)];
+
+static void iosapic_table_setup(void)
+{
+ struct pci_device *pci;
+ u32 *p;
+ u8 slot = 0, iosapic_intin = 0, irq_devno, bus_id;
+
+ irt_table_entries = 0;
+ memset(irt_table, 0, sizeof(irt_table));
+ p = irt_table;
+
+ foreachpci(pci) {
+ // if (!pci->irq) continue;
+ BUG_ON(irt_table_entries >= IRT_TABLE_ENTRIES);
+ irt_table_entries++;
+ dprintf(5, "IRT ENTRY #%d: bdf %02x\n", irt_table_entries, pci->bdf);
+ /* write the 16 bytes */
+ /* 1: entry_type, entry_length, interrupt_type, polarity_trigger */
+ *p++ = 0x8b10000f; // oder 0x8b10000d
+ /* 2: src_bus_irq_devno, src_bus_id, src_seg_id, dest_iosapic_intin */
+ /* irq_devno = (slot << 2) | (intr_pin-1); */
+ irq_devno = (slot++ << 2) | (pci->irq - 1);
+ bus_id = 0;
+ *p++ = (irq_devno << 24) | (bus_id << 16) | (0 << 8) | (iosapic_intin << 0);
+ *p++ = IOSAPIC_HPA >> 32;
+ *p++ = (u32) IOSAPIC_HPA;
+ }
+}
+
+static int pdc_pci_index(unsigned int *arg)
+{
+ unsigned long option = ARG1;
+ unsigned long *result = (unsigned long *)ARG2;
+ /* machines with Dino don't provide this info */
// dprintf(0, "\n\nSeaBIOS: PDC_PCI_INDEX(%lu) called with ARG2=%x ARG3=%x ARG4=%x\n", option, ARG2, ARG3, ARG4);
switch (option) {
@@ -1594,18 +1618,17 @@ static int pdc_pci_index(unsigned int *arg)
result[0] = 2; /* XXX physical hardware returns those ?!? */
return PDC_OK;
case PDC_PCI_GET_INT_TBL_SIZE:
- result[0] = IRT_TABLE_ENTRIES;
- return has_astro ? PDC_OK : PDC_BAD_OPTION;
+ if (!has_astro)
+ return PDC_BAD_OPTION;
+ result[0] = irt_table_entries;
+ return PDC_OK;
case PDC_PCI_GET_INT_TBL:
- result[0] = IRT_TABLE_ENTRIES;
- irt_table = (u32 *) ARG4; /* ptr to irt table */
- for (i = 0; i < IRT_TABLE_ENTRIES; i++) {
- *irt_table++ = irt_table_const[2 * i];
- *irt_table++ = irt_table_const[2 * i + 1];
- *irt_table++ = IOSAPIC_HPA >> 32;
- *irt_table++ = (u32) IOSAPIC_HPA;
- }
- return has_astro ? PDC_OK : PDC_BAD_OPTION;
+ if (!has_astro)
+ return PDC_BAD_OPTION;
+ result[0] = irt_table_entries;
+ /* ARG4 is ptr to irt table */
+ memcpy((void *)ARG4, irt_table, irt_table_entries * 16);
+ return PDC_OK;
case PDC_PCI_PCI_PATH_TO_PCI_HPA:
BUG_ON(1);
result[0] = has_astro ? 0xfed00000 : PCI_HPA;
@@ -2411,6 +2434,7 @@ void __VISIBLE start_parisc_firmware(void)
// coreboot_preinit();
pci_setup();
+ iosapic_table_setup();
serial_setup();
block_setup();