Index: mptbl.c =================================================================== --- mptbl.c (revision 265211) +++ mptbl.c (working copy) @@ -51,6 +51,7 @@ #define IOAPIC_PADDR 0xFEC00000 #define IOAPIC_VERSION 0x11 +#define IOAPIC_ID 0 #define MP_SPECREV 4 #define MPFP_SIG "_MP_" @@ -77,10 +78,10 @@ #define MPEII_NUM_LOCAL_IRQ 2 /* Bus entry defines */ -#define MPE_NUM_BUSES 2 #define MPE_BUSNAME_LEN 6 #define MPE_BUSNAME_ISA "ISA " #define MPE_BUSNAME_PCI "PCI " +static int isa_bus; static void *oem_tbl_start; static int oem_tbl_size; @@ -165,20 +166,36 @@ mpie->dst_apic_int = 1; } -static void +static int mpt_build_bus_entries(bus_entry_ptr mpeb) { + int bus, max_pcibus; + bus_entry_ptr mpeb_first; + mpeb_first = mpeb; + + max_pcibus = -1; + for (bus = 0; bus <= PCI_BUSMAX; bus++) { + if (pci_bus_configured(bus)) { + max_pcibus = bus; + memset(mpeb, 0, sizeof(*mpeb)); + mpeb->type = MPCT_ENTRY_BUS; + mpeb->bus_id = bus; + memcpy(mpeb->bus_type, MPE_BUSNAME_PCI, + MPE_BUSNAME_LEN); + mpeb++; + } + } + + isa_bus = max_pcibus + 1; + memset(mpeb, 0, sizeof(*mpeb)); mpeb->type = MPCT_ENTRY_BUS; - mpeb->bus_id = 0; - memcpy(mpeb->bus_type, MPE_BUSNAME_PCI, MPE_BUSNAME_LEN); + mpeb->bus_id = isa_bus; + memcpy(mpeb->bus_type, MPE_BUSNAME_ISA, MPE_BUSNAME_LEN); mpeb++; - memset(mpeb, 0, sizeof(*mpeb)); - mpeb->type = MPCT_ENTRY_BUS; - mpeb->bus_id = 1; - memcpy(mpeb->bus_type, MPE_BUSNAME_ISA, MPE_BUSNAME_LEN); + return (mpeb - mpeb_first); } static void @@ -233,7 +250,7 @@ } static void -mpt_build_ioint_entries(int_entry_ptr mpie, int id) +mpt_build_ioint_entries(int_entry_ptr mpie, int ioapic_id) { int pin, bus; @@ -247,12 +264,12 @@ for (pin = 0; pin < 16; pin++) { memset(mpie, 0, sizeof(*mpie)); mpie->type = MPCT_ENTRY_INT; - mpie->src_bus_id = 1; - mpie->dst_apic_id = id; + mpie->src_bus_id = isa_bus; + mpie->dst_apic_id = ioapic_id; /* * All default configs route IRQs from bus 0 to the first 16 - * pins of the first I/O APIC with an APIC ID of 2. + * pins of the first I/O APIC. */ mpie->dst_apic_int = pin; switch (pin) { @@ -303,7 +320,7 @@ proc_entry_ptr mpep; mpfps_t mpfp; int_entry_ptr mpie; - int ioints, bus; + int ioints, num_buses; char *curraddr; char *startaddr; @@ -313,21 +330,6 @@ return (ENOMEM); } - /* - * There is no way to advertise multiple PCI hierarchies via MPtable - * so require that there is no PCI hierarchy with a non-zero bus - * number. - */ - for (bus = 1; bus <= PCI_BUSMAX; bus++) { - if (pci_bus_configured(bus)) { - fprintf(stderr, "MPtable is incompatible with " - "multiple PCI hierarchies.\r\n"); - fprintf(stderr, "MPtable generation can be disabled " - "by passing the -Y option to bhyve(8).\r\n"); - return (EINVAL); - } - } - curraddr = startaddr; mpfp = (mpfps_t)curraddr; mpt_build_mpfp(mpfp, MPTABLE_BASE); @@ -343,18 +345,18 @@ mpch->entry_count += ncpu; mpeb = (bus_entry_ptr) curraddr; - mpt_build_bus_entries(mpeb); - curraddr += sizeof(*mpeb) * MPE_NUM_BUSES; - mpch->entry_count += MPE_NUM_BUSES; + num_buses = mpt_build_bus_entries(mpeb); + curraddr += sizeof(*mpeb) * num_buses; + mpch->entry_count += num_buses; mpei = (io_apic_entry_ptr)curraddr; - mpt_build_ioapic_entries(mpei, 0); + mpt_build_ioapic_entries(mpei, IOAPIC_ID); curraddr += sizeof(*mpei); mpch->entry_count++; mpie = (int_entry_ptr) curraddr; ioints = mpt_count_ioint_entries(); - mpt_build_ioint_entries(mpie, 0); + mpt_build_ioint_entries(mpie, IOAPIC_ID); curraddr += sizeof(*mpie) * ioints; mpch->entry_count += ioints;