PERFORCE change 192802 for review
John Baldwin
jhb at FreeBSD.org
Sun May 8 00:44:50 UTC 2011
http://p4web.freebsd.org/@@192802?ac=10
Change 192802 by jhb at jhb_fiver on 2011/05/08 00:44:27
Finish first cut at using MPTable info to determine which address ranges
Host-PCI bridges decode.
Affected files ...
.. //depot/projects/pci/sys/x86/include/mptable.h#4 edit
.. //depot/projects/pci/sys/x86/x86/mptable.c#4 edit
.. //depot/projects/pci/sys/x86/x86/mptable_pci.c#7 edit
Differences ...
==== //depot/projects/pci/sys/x86/include/mptable.h#4 (text+ko) ====
@@ -72,14 +72,14 @@
u_char reserved;
} *mpcth_t;
+/* Base table entries */
+
#define MPCT_ENTRY_PROCESSOR 0
#define MPCT_ENTRY_BUS 1
#define MPCT_ENTRY_IOAPIC 2
#define MPCT_ENTRY_INT 3
#define MPCT_ENTRY_LOCAL_INT 4
-/* Base table entries */
-
typedef struct PROCENTRY {
u_char type;
u_char apic_id;
@@ -141,6 +141,10 @@
u_char length;
} *ext_entry_ptr;
+#define MPCT_EXTENTRY_SAS 0x80
+#define MPCT_EXTENTRY_BHD 0x81
+#define MPCT_EXTENTRY_CBASM 0x82
+
typedef struct SASENTRY {
u_char type;
u_char length;
==== //depot/projects/pci/sys/x86/x86/mptable.c#4 (text+ko) ====
@@ -1083,16 +1083,123 @@
}
#ifdef NEW_PCIB
+struct host_res_args {
+ struct mptable_hostb_softc *sc;
+ device_t dev;
+ u_char bus;
+};
+
/*
* Initialize a Host-PCI bridge so it can restrict resource allocation
* requests to the resources it actually decodes according to MP
* config table extended entries.
*/
+static void
+mptable_host_res_handler(ext_entry_ptr *entry, void *arg)
+{
+ struct host_res_args *args;
+ cbasm_entry_ptr *cbasm;
+ sas_entry_ptr *sas;
+ const char *name;
+ uint64_t start, end;
+ int error, *flagp, flags, type;
+
+ args = arg;
+ switch (entry->type) {
+ case MPCT_EXTENTRY_SAS:
+ sas = (sas_entry_ptr *)entry;
+ if (sas->bus_id != args->bus)
+ break;
+ switch (sas->address_type) {
+ case SASENTRY_TYPE_IO:
+ type = SYS_RES_IOPORT;
+ flags = 0;
+ break;
+ case SASENTRY_TYPE_MEMORY:
+ type = SYS_RES_MEMORY;
+ flags = 0;
+ break;
+ case SASENTRY_TYPE_PREFETCH:
+ type = SYS_RES_MEMORY;
+ flags = RF_PREFETCHABLE;
+ break;
+ }
+ start = sas->address_base;
+ end = sas->address_base + sas->address_length - 1;
+#ifdef __i386__
+ if (start > ULONG_MAX) {
+ device_printf(args->dev,
+ "Ignoring %d range above 4GB (%#jx-%#jx)\n",
+ type, (uintmax_t)start, (uintmax_t)end);
+ break;
+ }
+ if (end > ULONG_MAX) {
+ device_printf(args->dev,
+ "Truncating end of range above 4GB (%#jx-%#jx)\n",
+ type, (uintmax_t)start, (uintmax_t)end);
+ end = ULONG_MAX;
+ }
+#endif
+ error = pcib_host_res_decodes(&args->sc->sc_host_res, type, start, end,
+ flags);
+ if (error)
+ panic("Failed to manage %d range (%#jx-%#jx): %d", type,
+ (uintmax_t)start, (uintmax_t)end, error);
+ break;
+ case MPCT_EXTENTRY_CBASM:
+ cbasm = (cbasm_entry_ptr *)entry;
+ if (cbasm->bus_id != args->bus)
+ break;
+ switch (cbasm->predefined_range) {
+ case CBASMENTRY_RANGE_ISA_IO:
+ flagp = &args->sc->sc_decodes_isa_io;
+ name = "ISA I/O";
+ break;
+ case CBASMENTRY_RANGE_VGA_IO:
+ flagp = &args->sc->sc_decodes_vga_io;
+ name = "VGA I/O";
+ break;
+ default:
+ printf(
+ "MPTable: Unknown compatiblity address space range for bus %u: %d\n",
+ cbasm->bus_id, cbasm->predefined_range);
+ return;
+ }
+ if (*flagp != 0)
+ printf("MPTable: Duplicate compatibility %s range for bus %u\n",
+ name, cbasm->bus_id);
+ switch (cbasm->address_mod) {
+ case CBASMENTRY_ADDRESS_MOD_ADD:
+ *flagp = 1;
+ if (bootverbose)
+ device_printf(args->dev, "decoding %s ports\n", name);
+ break;
+ case CBASMENTRY_ADDRESS_MOD_SUBTRACT:
+ *flagp = -1;
+ if (bootverbose)
+ device_printf(args->dev, "not decoding %s ports\n", name);
+ break;
+ default:
+ printf(
+ "MPTable: Unknown compatibility address space modifier: %u\n",
+ cbasm->address_mod);
+ break;
+ }
+ break;
+ }
+}
+
void
mptable_pci_host_res_init(device_t pcib)
{
- struct mptable_hostb_softc *sc;
+ struct host_res_args args;
- sc = device_get_softc(dev);
+ KASSERT(pci0 != -1, ("do not know how to map PCI bus IDs"));
+ args.bus = pci_get_bus(dev) + pci0;
+ args.dev = dev;
+ args.sc = device_get_softc(dev);
+ if (pcib_host_res_init(dev, &sc->sc_host_res) != 0)
+ panic("failed to init hostb resources");
+ mptable_walk_extended_table(mptable_host_res_handler, &args);
}
#endif
==== //depot/projects/pci/sys/x86/x86/mptable_pci.c#7 (text+ko) ====
@@ -109,6 +109,31 @@
}
#ifdef NEW_PCIB
+static int
+mptable_is_isa_range(u_long start, u_long end)
+{
+
+ if (end >= 0x10000)
+ return (0);
+ if (start & 0xfc00 != end & 0xfc00)
+ return (0);
+ start &= ~0xfc00;
+ end &- ~0xfc00;
+ return (start >= 0x100 && end <= 0x3ff);
+}
+
+static int
+mptable_is_vga_range(u_long start, u_long end)
+{
+ if (end >= 0x10000)
+ return (0);
+ if (start & 0xfc00 != end & 0xfc00)
+ return (0);
+ start &= ~0xfc00;
+ end &- ~0xfc00;
+ return (pci_is_vga_ioport_range(start, end));
+}
+
static struct resource *
mptable_hostb_alloc_resource(device_t dev, device_t child, int type, int *rid,
u_long start, u_long end, u_long count, u_int flags)
@@ -116,7 +141,30 @@
struct mptable_hostb_softc *sc;
sc = device_get_softc(dev);
- /* XXX: Special handling for VGA and ISA I/O ranges. */
+ if (type == SYS_RES_IOPORT && start + count - 1 == end) {
+ if (mptable_is_isa_range(start, end)) {
+ switch (sc->sc_decodes_isa_io) {
+ case -1:
+ return (NULL);
+ case 1:
+ return (bus_generic_alloc_resource(dev, child, type, rid,
+ start, end, count, flags));
+ default:
+ break;
+ }
+ }
+ if (mptable_is_vga_range(start, end)) {
+ switch (sc->sc_decodes_vga_io) {
+ case -1:
+ return (NULL);
+ case 1:
+ return (bus_generic_alloc_resource(dev, child, type, rid,
+ start, end, count, flags));
+ default:
+ break;
+ }
+ }
+ }
return (pcib_host_res_alloc(&sc->sc_host_res, child, type, rid, start,
end, count, flags));
}
More information about the p4-projects
mailing list