The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/x86/x86/mptable.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 1996, by Steve Passe
    3  * All rights reserved.
    4  * Copyright (c) 2003 John Baldwin <jhb@FreeBSD.org>
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. The name of the developer may NOT be used to endorse or promote products
   12  *    derived from this software without specific prior written permission.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24  * SUCH DAMAGE.
   25  */
   26 
   27 #include <sys/cdefs.h>
   28 __FBSDID("$FreeBSD$");
   29 
   30 #include "opt_mptable_force_htt.h"
   31 #include <sys/param.h>
   32 #include <sys/systm.h>
   33 #include <sys/bus.h>
   34 #include <sys/kernel.h>
   35 #include <sys/limits.h>
   36 #include <sys/malloc.h>
   37 #ifdef NEW_PCIB
   38 #include <sys/rman.h>
   39 #endif
   40 
   41 #include <vm/vm.h>
   42 #include <vm/vm_param.h>
   43 #include <vm/pmap.h>
   44 
   45 #include <dev/pci/pcivar.h>
   46 #ifdef NEW_PCIB
   47 #include <dev/pci/pcib_private.h>
   48 #endif
   49 #include <x86/apicreg.h>
   50 #include <x86/mptable.h>
   51 #include <machine/frame.h>
   52 #include <machine/intr_machdep.h>
   53 #include <x86/apicvar.h>
   54 #include <machine/md_var.h>
   55 #ifdef NEW_PCIB
   56 #include <machine/resource.h>
   57 #endif
   58 #include <machine/specialreg.h>
   59 
   60 /* string defined by the Intel MP Spec as identifying the MP table */
   61 #define MP_SIG                  0x5f504d5f      /* _MP_ */
   62 
   63 #ifdef __amd64__
   64 #define MAX_LAPIC_ID            63      /* Max local APIC ID for HTT fixup */
   65 #else
   66 #define MAX_LAPIC_ID            31      /* Max local APIC ID for HTT fixup */
   67 #endif
   68 
   69 #ifdef PC98
   70 #define BIOS_BASE               (0xe8000)
   71 #define BIOS_SIZE               (0x18000)
   72 #else
   73 #define BIOS_BASE               (0xf0000)
   74 #define BIOS_SIZE               (0x10000)
   75 #endif
   76 #define BIOS_COUNT              (BIOS_SIZE/4)
   77 
   78 typedef void mptable_entry_handler(u_char *entry, void *arg);
   79 typedef void mptable_extended_entry_handler(ext_entry_ptr entry, void *arg);
   80 
   81 /* descriptions of MP table entries */
   82 typedef struct BASETABLE_ENTRY {
   83         uint8_t type;
   84         uint8_t length;
   85         uint8_t name[16];
   86 }       basetable_entry;
   87 
   88 static basetable_entry basetable_entry_types[] =
   89 {
   90         {0, 20, "Processor"},
   91         {1, 8, "Bus"},
   92         {2, 8, "I/O APIC"},
   93         {3, 8, "I/O INT"},
   94         {4, 8, "Local INT"}
   95 };
   96 
   97 typedef struct BUSDATA {
   98         u_char  bus_id;
   99         enum busTypes bus_type;
  100 }       bus_datum;
  101 
  102 typedef struct INTDATA {
  103         u_char  int_type;
  104         u_short int_flags;
  105         u_char  src_bus_id;
  106         u_char  src_bus_irq;
  107         u_char  dst_apic_id;
  108         u_char  dst_apic_int;
  109         u_char  int_vector;
  110 }       io_int, local_int;
  111 
  112 typedef struct BUSTYPENAME {
  113         u_char  type;
  114         char    name[7];
  115 }       bus_type_name;
  116 
  117 /* From MP spec v1.4, table 4-8. */
  118 static bus_type_name bus_type_table[] =
  119 {
  120         {UNKNOWN_BUSTYPE, "CBUS  "},
  121         {UNKNOWN_BUSTYPE, "CBUSII"},
  122         {EISA, "EISA  "},
  123         {UNKNOWN_BUSTYPE, "FUTURE"},
  124         {UNKNOWN_BUSTYPE, "INTERN"},
  125         {ISA, "ISA   "},
  126         {UNKNOWN_BUSTYPE, "MBI   "},
  127         {UNKNOWN_BUSTYPE, "MBII  "},
  128         {MCA, "MCA   "},
  129         {UNKNOWN_BUSTYPE, "MPI   "},
  130         {UNKNOWN_BUSTYPE, "MPSA  "},
  131         {UNKNOWN_BUSTYPE, "NUBUS "},
  132         {PCI, "PCI   "},
  133         {UNKNOWN_BUSTYPE, "PCMCIA"},
  134         {UNKNOWN_BUSTYPE, "TC    "},
  135         {UNKNOWN_BUSTYPE, "VL    "},
  136         {UNKNOWN_BUSTYPE, "VME   "},
  137         {UNKNOWN_BUSTYPE, "XPRESS"}
  138 };
  139 
  140 /* From MP spec v1.4, table 5-1. */
  141 static int default_data[7][5] =
  142 {
  143 /*   nbus, id0, type0, id1, type1 */
  144         {1, 0, ISA, 255, NOBUS},
  145         {1, 0, EISA, 255, NOBUS},
  146         {1, 0, EISA, 255, NOBUS},
  147         {1, 0, MCA, 255, NOBUS},
  148         {2, 0, ISA, 1, PCI},
  149         {2, 0, EISA, 1, PCI},
  150         {2, 0, MCA, 1, PCI}
  151 };
  152 
  153 struct pci_probe_table_args {
  154         u_char bus;
  155         u_char found;
  156 };
  157 
  158 struct pci_route_interrupt_args {
  159         u_char bus;             /* Source bus. */
  160         u_char irq;             /* Source slot:pin. */
  161         int vector;             /* Return value. */
  162 };
  163 
  164 static mpfps_t mpfps;
  165 static mpcth_t mpct;
  166 static ext_entry_ptr mpet;
  167 static void *ioapics[MAX_APIC_ID + 1];
  168 static bus_datum *busses;
  169 static int mptable_nioapics, mptable_nbusses, mptable_maxbusid;
  170 static int pci0 = -1;
  171 
  172 static MALLOC_DEFINE(M_MPTABLE, "mptable", "MP Table Items");
  173 
  174 static enum intr_polarity conforming_polarity(u_char src_bus,
  175             u_char src_bus_irq);
  176 static enum intr_trigger conforming_trigger(u_char src_bus, u_char src_bus_irq);
  177 static enum intr_polarity intentry_polarity(int_entry_ptr intr);
  178 static enum intr_trigger intentry_trigger(int_entry_ptr intr);
  179 static int      lookup_bus_type(char *name);
  180 static void     mptable_count_items(void);
  181 static void     mptable_count_items_handler(u_char *entry, void *arg);
  182 #ifdef MPTABLE_FORCE_HTT
  183 static void     mptable_hyperthread_fixup(u_int id_mask);
  184 #endif
  185 static void     mptable_parse_apics_and_busses(void);
  186 static void     mptable_parse_apics_and_busses_handler(u_char *entry,
  187     void *arg);
  188 static void     mptable_parse_default_config_ints(void);
  189 static void     mptable_parse_ints(void);
  190 static void     mptable_parse_ints_handler(u_char *entry, void *arg);
  191 static void     mptable_parse_io_int(int_entry_ptr intr);
  192 static void     mptable_parse_local_int(int_entry_ptr intr);
  193 static void     mptable_pci_probe_table_handler(u_char *entry, void *arg);
  194 static void     mptable_pci_route_interrupt_handler(u_char *entry, void *arg);
  195 static void     mptable_pci_setup(void);
  196 static int      mptable_probe(void);
  197 static int      mptable_probe_cpus(void);
  198 static void     mptable_probe_cpus_handler(u_char *entry, void *arg __unused);
  199 static void     mptable_register(void *dummy);
  200 static int      mptable_setup_local(void);
  201 static int      mptable_setup_io(void);
  202 #ifdef NEW_PCIB
  203 static void     mptable_walk_extended_table(
  204     mptable_extended_entry_handler *handler, void *arg);
  205 #endif
  206 static void     mptable_walk_table(mptable_entry_handler *handler, void *arg);
  207 static int      search_for_sig(u_int32_t target, int count);
  208 
  209 static struct apic_enumerator mptable_enumerator = {
  210         "MPTable",
  211         mptable_probe,
  212         mptable_probe_cpus,
  213         mptable_setup_local,
  214         mptable_setup_io
  215 };
  216 
  217 /*
  218  * look for the MP spec signature
  219  */
  220 
  221 static int
  222 search_for_sig(u_int32_t target, int count)
  223 {
  224         int     x;
  225         u_int32_t *addr = (u_int32_t *) (KERNBASE + target);
  226 
  227         for (x = 0; x < count; x += 4)
  228                 if (addr[x] == MP_SIG)
  229                         /* make array index a byte index */
  230                         return (target + (x * sizeof(u_int32_t)));
  231         return (-1);
  232 }
  233 
  234 static int
  235 lookup_bus_type(char *name)
  236 {
  237         int     x;
  238 
  239         for (x = 0; x < MAX_BUSTYPE; ++x)
  240                 if (strncmp(bus_type_table[x].name, name, 6) == 0)
  241                         return (bus_type_table[x].type);
  242 
  243         return (UNKNOWN_BUSTYPE);
  244 }
  245 
  246 /*
  247  * Look for an Intel MP spec table (ie, SMP capable hardware).
  248  */
  249 static int
  250 mptable_probe(void)
  251 {
  252         int     x;
  253         u_long  segment;
  254         u_int32_t target;
  255 
  256         /* see if EBDA exists */
  257         if ((segment = (u_long) * (u_short *) (KERNBASE + 0x40e)) != 0) {
  258                 /* search first 1K of EBDA */
  259                 target = (u_int32_t) (segment << 4);
  260                 if ((x = search_for_sig(target, 1024 / 4)) >= 0)
  261                         goto found;
  262         } else {
  263                 /* last 1K of base memory, effective 'top of base' passed in */
  264                 target = (u_int32_t) ((basemem * 1024) - 0x400);
  265                 if ((x = search_for_sig(target, 1024 / 4)) >= 0)
  266                         goto found;
  267         }
  268 
  269         /* search the BIOS */
  270         target = (u_int32_t) BIOS_BASE;
  271         if ((x = search_for_sig(target, BIOS_COUNT)) >= 0)
  272                 goto found;
  273 
  274         /* nothing found */
  275         return (ENXIO);
  276 
  277 found:
  278         mpfps = (mpfps_t)(KERNBASE + x);
  279 
  280         /* Map in the configuration table if it exists. */
  281         if (mpfps->config_type != 0) {
  282                 if (bootverbose)
  283                         printf(
  284                 "MP Table version 1.%d found using Default Configuration %d\n",
  285                             mpfps->spec_rev, mpfps->config_type);
  286                 if (mpfps->config_type != 5 && mpfps->config_type != 6) {
  287                         printf(
  288                         "MP Table Default Configuration %d is unsupported\n",
  289                             mpfps->config_type);
  290                         return (ENXIO);
  291                 }
  292                 mpct = NULL;
  293         } else {
  294                 if ((uintptr_t)mpfps->pap >= 1024 * 1024) {
  295                         printf("%s: Unable to map MP Configuration Table\n",
  296                             __func__);
  297                         return (ENXIO);
  298                 }
  299                 mpct = (mpcth_t)(KERNBASE + (uintptr_t)mpfps->pap);
  300                 if (mpct->base_table_length + (uintptr_t)mpfps->pap >=
  301                     1024 * 1024) {
  302                         printf("%s: Unable to map end of MP Config Table\n",
  303                             __func__);
  304                         return (ENXIO);
  305                 }
  306                 if (mpct->extended_table_length != 0 &&
  307                     mpct->extended_table_length + mpct->base_table_length +
  308                     (uintptr_t)mpfps->pap < 1024 * 1024)
  309                         mpet = (ext_entry_ptr)((char *)mpct +
  310                             mpct->base_table_length);
  311                 if (mpct->signature[0] != 'P' || mpct->signature[1] != 'C' ||
  312                     mpct->signature[2] != 'M' || mpct->signature[3] != 'P') {
  313                         printf("%s: MP Config Table has bad signature: %c%c%c%c\n",
  314                             __func__, mpct->signature[0], mpct->signature[1],
  315                             mpct->signature[2], mpct->signature[3]);
  316                         return (ENXIO);
  317                 }
  318                 if (bootverbose)
  319                         printf(
  320                         "MP Configuration Table version 1.%d found at %p\n",
  321                             mpct->spec_rev, mpct);
  322         }
  323 
  324         return (-100);
  325 }
  326 
  327 /*
  328  * Run through the MP table enumerating CPUs.
  329  */
  330 static int
  331 mptable_probe_cpus(void)
  332 {
  333         u_int cpu_mask;
  334 
  335         /* Is this a pre-defined config? */
  336         if (mpfps->config_type != 0) {
  337                 lapic_create(0, 1);
  338                 lapic_create(1, 0);
  339         } else {
  340                 cpu_mask = 0;
  341                 mptable_walk_table(mptable_probe_cpus_handler, &cpu_mask);
  342 #ifdef MPTABLE_FORCE_HTT
  343                 mptable_hyperthread_fixup(cpu_mask);
  344 #endif
  345         }
  346         return (0);
  347 }
  348 
  349 /*
  350  * Initialize the local APIC on the BSP.
  351  */
  352 static int
  353 mptable_setup_local(void)
  354 {
  355         vm_paddr_t addr;
  356 
  357         /* Is this a pre-defined config? */
  358         printf("MPTable: <");
  359         if (mpfps->config_type != 0) {
  360                 addr = DEFAULT_APIC_BASE;
  361                 printf("Default Configuration %d", mpfps->config_type);
  362         } else {
  363                 addr = mpct->apic_address;
  364                 printf("%.*s %.*s", (int)sizeof(mpct->oem_id), mpct->oem_id,
  365                     (int)sizeof(mpct->product_id), mpct->product_id);
  366         }
  367         printf(">\n");
  368         lapic_init(addr);
  369         return (0);
  370 }
  371 
  372 /*
  373  * Run through the MP table enumerating I/O APICs.
  374  */
  375 static int
  376 mptable_setup_io(void)
  377 {
  378         int i;
  379         u_char byte;
  380 
  381         /* First, we count individual items and allocate arrays. */
  382         mptable_count_items();
  383         busses = malloc((mptable_maxbusid + 1) * sizeof(bus_datum), M_MPTABLE,
  384             M_WAITOK);
  385         for (i = 0; i <= mptable_maxbusid; i++)
  386                 busses[i].bus_type = NOBUS;
  387 
  388         /* Second, we run through adding I/O APIC's and busses. */
  389         mptable_parse_apics_and_busses();       
  390 
  391         /* Third, we run through the table tweaking interrupt sources. */
  392         mptable_parse_ints();
  393 
  394         /* Fourth, we register all the I/O APIC's. */
  395         for (i = 0; i <= MAX_APIC_ID; i++)
  396                 if (ioapics[i] != NULL)
  397                         ioapic_register(ioapics[i]);
  398 
  399         /* Fifth, we setup data structures to handle PCI interrupt routing. */
  400         mptable_pci_setup();
  401 
  402         /* Finally, we throw the switch to enable the I/O APIC's. */
  403         if (mpfps->mpfb2 & MPFB2_IMCR_PRESENT) {
  404                 outb(0x22, 0x70);       /* select IMCR */
  405                 byte = inb(0x23);       /* current contents */
  406                 byte |= 0x01;           /* mask external INTR */
  407                 outb(0x23, byte);       /* disconnect 8259s/NMI */
  408         }
  409 
  410         return (0);
  411 }
  412 
  413 static void
  414 mptable_register(void *dummy __unused)
  415 {
  416 
  417         apic_register_enumerator(&mptable_enumerator);
  418 }
  419 SYSINIT(mptable_register, SI_SUB_TUNABLES - 1, SI_ORDER_FIRST, mptable_register,
  420     NULL);
  421 
  422 /*
  423  * Call the handler routine for each entry in the MP config base table.
  424  */
  425 static void
  426 mptable_walk_table(mptable_entry_handler *handler, void *arg)
  427 {
  428         u_int i;
  429         u_char *entry;
  430 
  431         entry = (u_char *)(mpct + 1);
  432         for (i = 0; i < mpct->entry_count; i++) {
  433                 switch (*entry) {
  434                 case MPCT_ENTRY_PROCESSOR:
  435                 case MPCT_ENTRY_IOAPIC:
  436                 case MPCT_ENTRY_BUS:
  437                 case MPCT_ENTRY_INT:
  438                 case MPCT_ENTRY_LOCAL_INT:
  439                         break;
  440                 default:
  441                         panic("%s: Unknown MP Config Entry %d\n", __func__,
  442                             (int)*entry);
  443                 }
  444                 handler(entry, arg);
  445                 entry += basetable_entry_types[*entry].length;
  446         }
  447 }
  448 
  449 #ifdef NEW_PCIB
  450 /*
  451  * Call the handler routine for each entry in the MP config extended
  452  * table.
  453  */
  454 static void
  455 mptable_walk_extended_table(mptable_extended_entry_handler *handler, void *arg)
  456 {
  457         ext_entry_ptr end, entry;
  458 
  459         if (mpet == NULL)
  460                 return;
  461         entry = mpet;
  462         end = (ext_entry_ptr)((char *)mpet + mpct->extended_table_length);
  463         while (entry < end) {
  464                 handler(entry, arg);
  465                 entry = (ext_entry_ptr)((char *)entry + entry->length);
  466         }
  467 }
  468 #endif
  469 
  470 static void
  471 mptable_probe_cpus_handler(u_char *entry, void *arg)
  472 {
  473         proc_entry_ptr proc;
  474         u_int *cpu_mask;
  475 
  476         switch (*entry) {
  477         case MPCT_ENTRY_PROCESSOR:
  478                 proc = (proc_entry_ptr)entry;
  479                 if (proc->cpu_flags & PROCENTRY_FLAG_EN) {
  480                         lapic_create(proc->apic_id, proc->cpu_flags &
  481                             PROCENTRY_FLAG_BP);
  482                         if (proc->apic_id < MAX_LAPIC_ID) {
  483                                 cpu_mask = (u_int *)arg;
  484                                 *cpu_mask |= (1ul << proc->apic_id);
  485                         }
  486                 }
  487                 break;
  488         }
  489 }
  490 
  491 static void
  492 mptable_count_items_handler(u_char *entry, void *arg __unused)
  493 {
  494         io_apic_entry_ptr apic;
  495         bus_entry_ptr bus;
  496 
  497         switch (*entry) {
  498         case MPCT_ENTRY_BUS:
  499                 bus = (bus_entry_ptr)entry;
  500                 mptable_nbusses++;
  501                 if (bus->bus_id > mptable_maxbusid)
  502                         mptable_maxbusid = bus->bus_id;
  503                 break;
  504         case MPCT_ENTRY_IOAPIC:
  505                 apic = (io_apic_entry_ptr)entry;
  506                 if (apic->apic_flags & IOAPICENTRY_FLAG_EN)
  507                         mptable_nioapics++;
  508                 break;
  509         }
  510 }
  511 
  512 /*
  513  * Count items in the table.
  514  */
  515 static void
  516 mptable_count_items(void)
  517 {
  518 
  519         /* Is this a pre-defined config? */
  520         if (mpfps->config_type != 0) {
  521                 mptable_nioapics = 1;
  522                 switch (mpfps->config_type) {
  523                 case 1:
  524                 case 2:
  525                 case 3:
  526                 case 4:
  527                         mptable_nbusses = 1;
  528                         break;
  529                 case 5:
  530                 case 6:
  531                 case 7:
  532                         mptable_nbusses = 2;
  533                         break;
  534                 default:
  535                         panic("Unknown pre-defined MP Table config type %d",
  536                             mpfps->config_type);
  537                 }
  538                 mptable_maxbusid = mptable_nbusses - 1;
  539         } else
  540                 mptable_walk_table(mptable_count_items_handler, NULL);
  541 }
  542 
  543 /*
  544  * Add a bus or I/O APIC from an entry in the table.
  545  */
  546 static void
  547 mptable_parse_apics_and_busses_handler(u_char *entry, void *arg __unused)
  548 {
  549         io_apic_entry_ptr apic;
  550         bus_entry_ptr bus;
  551         enum busTypes bus_type;
  552         int i;
  553 
  554 
  555         switch (*entry) {
  556         case MPCT_ENTRY_BUS:
  557                 bus = (bus_entry_ptr)entry;
  558                 bus_type = lookup_bus_type(bus->bus_type);
  559                 if (bus_type == UNKNOWN_BUSTYPE) {
  560                         printf("MPTable: Unknown bus %d type \"", bus->bus_id);
  561                         for (i = 0; i < 6; i++)
  562                                 printf("%c", bus->bus_type[i]);
  563                         printf("\"\n");
  564                 }
  565                 busses[bus->bus_id].bus_id = bus->bus_id;
  566                 busses[bus->bus_id].bus_type = bus_type;
  567                 break;
  568         case MPCT_ENTRY_IOAPIC:
  569                 apic = (io_apic_entry_ptr)entry;
  570                 if (!(apic->apic_flags & IOAPICENTRY_FLAG_EN))
  571                         break;
  572                 if (apic->apic_id > MAX_APIC_ID)
  573                         panic("%s: I/O APIC ID %d too high", __func__,
  574                             apic->apic_id);
  575                 if (ioapics[apic->apic_id] != NULL)
  576                         panic("%s: Double APIC ID %d", __func__,
  577                             apic->apic_id);
  578                 ioapics[apic->apic_id] = ioapic_create(apic->apic_address,
  579                     apic->apic_id, -1);
  580                 break;
  581         default:
  582                 break;
  583         }
  584 }
  585 
  586 /*
  587  * Enumerate I/O APIC's and busses.
  588  */
  589 static void
  590 mptable_parse_apics_and_busses(void)
  591 {
  592 
  593         /* Is this a pre-defined config? */
  594         if (mpfps->config_type != 0) {
  595                 ioapics[2] = ioapic_create(DEFAULT_IO_APIC_BASE, 2, 0);
  596                 busses[0].bus_id = 0;
  597                 busses[0].bus_type = default_data[mpfps->config_type - 1][2];
  598                 if (mptable_nbusses > 1) {
  599                         busses[1].bus_id = 1;
  600                         busses[1].bus_type =
  601                             default_data[mpfps->config_type - 1][4];
  602                 }
  603         } else
  604                 mptable_walk_table(mptable_parse_apics_and_busses_handler,
  605                     NULL);
  606 }
  607 
  608 /*
  609  * Determine conforming polarity for a given bus type.
  610  */
  611 static enum intr_polarity
  612 conforming_polarity(u_char src_bus, u_char src_bus_irq)
  613 {
  614 
  615         KASSERT(src_bus <= mptable_maxbusid, ("bus id %d too large", src_bus));
  616         switch (busses[src_bus].bus_type) {
  617         case ISA:
  618         case EISA:
  619                 return (INTR_POLARITY_HIGH);
  620         case PCI:
  621                 return (INTR_POLARITY_LOW);
  622         default:
  623                 panic("%s: unknown bus type %d", __func__,
  624                     busses[src_bus].bus_type);
  625         }
  626 }
  627 
  628 /*
  629  * Determine conforming trigger for a given bus type.
  630  */
  631 static enum intr_trigger
  632 conforming_trigger(u_char src_bus, u_char src_bus_irq)
  633 {
  634 
  635         KASSERT(src_bus <= mptable_maxbusid, ("bus id %d too large", src_bus));
  636         switch (busses[src_bus].bus_type) {
  637         case ISA:
  638 #ifndef PC98
  639                 if (elcr_found)
  640                         return (elcr_read_trigger(src_bus_irq));
  641                 else
  642 #endif
  643                         return (INTR_TRIGGER_EDGE);
  644         case PCI:
  645                 return (INTR_TRIGGER_LEVEL);
  646 #ifndef PC98
  647         case EISA:
  648                 KASSERT(src_bus_irq < 16, ("Invalid EISA IRQ %d", src_bus_irq));
  649                 KASSERT(elcr_found, ("Missing ELCR"));
  650                 return (elcr_read_trigger(src_bus_irq));
  651 #endif
  652         default:
  653                 panic("%s: unknown bus type %d", __func__,
  654                     busses[src_bus].bus_type);
  655         }
  656 }
  657 
  658 static enum intr_polarity
  659 intentry_polarity(int_entry_ptr intr)
  660 {
  661 
  662         switch (intr->int_flags & INTENTRY_FLAGS_POLARITY) {
  663         case INTENTRY_FLAGS_POLARITY_CONFORM:
  664                 return (conforming_polarity(intr->src_bus_id,
  665                             intr->src_bus_irq));
  666         case INTENTRY_FLAGS_POLARITY_ACTIVEHI:
  667                 return (INTR_POLARITY_HIGH);
  668         case INTENTRY_FLAGS_POLARITY_ACTIVELO:
  669                 return (INTR_POLARITY_LOW);
  670         default:
  671                 panic("Bogus interrupt flags");
  672         }
  673 }
  674 
  675 static enum intr_trigger
  676 intentry_trigger(int_entry_ptr intr)
  677 {
  678 
  679         switch (intr->int_flags & INTENTRY_FLAGS_TRIGGER) {
  680         case INTENTRY_FLAGS_TRIGGER_CONFORM:
  681                 return (conforming_trigger(intr->src_bus_id,
  682                             intr->src_bus_irq));
  683         case INTENTRY_FLAGS_TRIGGER_EDGE:
  684                 return (INTR_TRIGGER_EDGE);
  685         case INTENTRY_FLAGS_TRIGGER_LEVEL:
  686                 return (INTR_TRIGGER_LEVEL);
  687         default:
  688                 panic("Bogus interrupt flags");
  689         }
  690 }
  691 
  692 /*
  693  * Parse an interrupt entry for an I/O interrupt routed to a pin on an I/O APIC.
  694  */
  695 static void
  696 mptable_parse_io_int(int_entry_ptr intr)
  697 {
  698         void *ioapic;
  699         u_int pin, apic_id;
  700 
  701         apic_id = intr->dst_apic_id;
  702         if (intr->dst_apic_id == 0xff) {
  703                 /*
  704                  * An APIC ID of 0xff means that the interrupt is connected
  705                  * to the specified pin on all I/O APICs in the system.  If
  706                  * there is only one I/O APIC, then use that APIC to route
  707                  * the interrupts.  If there is more than one I/O APIC, then
  708                  * punt.
  709                  */
  710                 if (mptable_nioapics == 1) {
  711                         apic_id = 0;
  712                         while (ioapics[apic_id] == NULL)
  713                                 apic_id++;
  714                 } else {
  715                         printf(
  716                         "MPTable: Ignoring global interrupt entry for pin %d\n",
  717                             intr->dst_apic_int);
  718                         return;
  719                 }
  720         }
  721         if (apic_id > MAX_APIC_ID) {
  722                 printf("MPTable: Ignoring interrupt entry for ioapic%d\n",
  723                     intr->dst_apic_id);
  724                 return;
  725         }
  726         ioapic = ioapics[apic_id];
  727         if (ioapic == NULL) {
  728                 printf(
  729         "MPTable: Ignoring interrupt entry for missing ioapic%d\n",
  730                     apic_id);
  731                 return;
  732         }
  733         pin = intr->dst_apic_int;
  734         switch (intr->int_type) {
  735         case INTENTRY_TYPE_INT:
  736                 switch (busses[intr->src_bus_id].bus_type) {
  737                 case NOBUS:
  738                         panic("interrupt from missing bus");
  739                 case ISA:
  740                 case EISA:
  741                         if (busses[intr->src_bus_id].bus_type == ISA)
  742                                 ioapic_set_bus(ioapic, pin, APIC_BUS_ISA);
  743                         else
  744                                 ioapic_set_bus(ioapic, pin, APIC_BUS_EISA);
  745                         if (intr->src_bus_irq == pin)
  746                                 break;
  747                         ioapic_remap_vector(ioapic, pin, intr->src_bus_irq);
  748                         if (ioapic_get_vector(ioapic, intr->src_bus_irq) ==
  749                             intr->src_bus_irq)
  750                                 ioapic_disable_pin(ioapic, intr->src_bus_irq);
  751                         break;
  752                 case PCI:
  753                         ioapic_set_bus(ioapic, pin, APIC_BUS_PCI);
  754                         break;
  755                 default:
  756                         ioapic_set_bus(ioapic, pin, APIC_BUS_UNKNOWN);
  757                         break;
  758                 }
  759                 break;
  760         case INTENTRY_TYPE_NMI:
  761                 ioapic_set_nmi(ioapic, pin);
  762                 break;
  763         case INTENTRY_TYPE_SMI:
  764                 ioapic_set_smi(ioapic, pin);
  765                 break;
  766         case INTENTRY_TYPE_EXTINT:
  767                 ioapic_set_extint(ioapic, pin);
  768                 break;
  769         default:
  770                 panic("%s: invalid interrupt entry type %d\n", __func__,
  771                     intr->int_type);
  772         }
  773         if (intr->int_type == INTENTRY_TYPE_INT ||
  774             (intr->int_flags & INTENTRY_FLAGS_TRIGGER) !=
  775             INTENTRY_FLAGS_TRIGGER_CONFORM)
  776                 ioapic_set_triggermode(ioapic, pin, intentry_trigger(intr));
  777         if (intr->int_type == INTENTRY_TYPE_INT ||
  778             (intr->int_flags & INTENTRY_FLAGS_POLARITY) !=
  779             INTENTRY_FLAGS_POLARITY_CONFORM)
  780                 ioapic_set_polarity(ioapic, pin, intentry_polarity(intr));
  781 }
  782 
  783 /*
  784  * Parse an interrupt entry for a local APIC LVT pin.
  785  */
  786 static void
  787 mptable_parse_local_int(int_entry_ptr intr)
  788 {
  789         u_int apic_id, pin;
  790 
  791         if (intr->dst_apic_id == 0xff)
  792                 apic_id = APIC_ID_ALL;
  793         else
  794                 apic_id = intr->dst_apic_id;
  795         if (intr->dst_apic_int == 0)
  796                 pin = APIC_LVT_LINT0;
  797         else
  798                 pin = APIC_LVT_LINT1;
  799         switch (intr->int_type) {
  800         case INTENTRY_TYPE_INT:
  801 #if 1
  802                 printf(
  803         "MPTable: Ignoring vectored local interrupt for LINTIN%d vector %d\n",
  804                     intr->dst_apic_int, intr->src_bus_irq);
  805                 return;
  806 #else
  807                 lapic_set_lvt_mode(apic_id, pin, APIC_LVT_DM_FIXED);
  808                 break;
  809 #endif
  810         case INTENTRY_TYPE_NMI:
  811                 lapic_set_lvt_mode(apic_id, pin, APIC_LVT_DM_NMI);
  812                 break;
  813         case INTENTRY_TYPE_SMI:
  814                 lapic_set_lvt_mode(apic_id, pin, APIC_LVT_DM_SMI);
  815                 break;
  816         case INTENTRY_TYPE_EXTINT:
  817                 lapic_set_lvt_mode(apic_id, pin, APIC_LVT_DM_EXTINT);
  818                 break;
  819         default:
  820                 panic("%s: invalid interrupt entry type %d\n", __func__,
  821                     intr->int_type);
  822         }
  823         if ((intr->int_flags & INTENTRY_FLAGS_TRIGGER) !=
  824             INTENTRY_FLAGS_TRIGGER_CONFORM)
  825                 lapic_set_lvt_triggermode(apic_id, pin,
  826                     intentry_trigger(intr));
  827         if ((intr->int_flags & INTENTRY_FLAGS_POLARITY) !=
  828             INTENTRY_FLAGS_POLARITY_CONFORM)
  829                 lapic_set_lvt_polarity(apic_id, pin, intentry_polarity(intr));
  830 }
  831 
  832 /*
  833  * Parse interrupt entries.
  834  */
  835 static void
  836 mptable_parse_ints_handler(u_char *entry, void *arg __unused)
  837 {
  838         int_entry_ptr intr;
  839 
  840         intr = (int_entry_ptr)entry;
  841         switch (*entry) {
  842         case MPCT_ENTRY_INT:
  843                 mptable_parse_io_int(intr);
  844                 break;
  845         case MPCT_ENTRY_LOCAL_INT:
  846                 mptable_parse_local_int(intr);
  847                 break;
  848         }
  849 }
  850 
  851 /*
  852  * Configure interrupt pins for a default configuration.  For details see
  853  * Table 5-2 in Section 5 of the MP Table specification.
  854  */
  855 static void
  856 mptable_parse_default_config_ints(void)
  857 {
  858         struct INTENTRY entry;
  859         int pin;
  860 
  861         /*
  862          * All default configs route IRQs from bus 0 to the first 16 pins
  863          * of the first I/O APIC with an APIC ID of 2.
  864          */
  865         entry.type = MPCT_ENTRY_INT;
  866         entry.int_flags = INTENTRY_FLAGS_POLARITY_CONFORM |
  867             INTENTRY_FLAGS_TRIGGER_CONFORM;
  868         entry.src_bus_id = 0;
  869         entry.dst_apic_id = 2;
  870 
  871         /* Run through all 16 pins. */
  872         for (pin = 0; pin < 16; pin++) {
  873                 entry.dst_apic_int = pin;
  874                 switch (pin) {
  875                 case 0:
  876                         /* Pin 0 is an ExtINT pin. */
  877                         entry.int_type = INTENTRY_TYPE_EXTINT;
  878                         break;
  879                 case 2:
  880                         /* IRQ 0 is routed to pin 2. */
  881                         entry.int_type = INTENTRY_TYPE_INT;
  882                         entry.src_bus_irq = 0;
  883                         break;
  884                 default:
  885                         /* All other pins are identity mapped. */
  886                         entry.int_type = INTENTRY_TYPE_INT;
  887                         entry.src_bus_irq = pin;
  888                         break;
  889                 }
  890                 mptable_parse_io_int(&entry);
  891         }
  892 
  893         /* Certain configs disable certain pins. */
  894         if (mpfps->config_type == 7)
  895                 ioapic_disable_pin(ioapics[2], 0);
  896         if (mpfps->config_type == 2) {
  897                 ioapic_disable_pin(ioapics[2], 2);
  898                 ioapic_disable_pin(ioapics[2], 13);
  899         }
  900 }
  901 
  902 /*
  903  * Configure the interrupt pins
  904  */
  905 static void
  906 mptable_parse_ints(void)
  907 {
  908 
  909         /* Is this a pre-defined config? */
  910         if (mpfps->config_type != 0) {
  911                 /* Configure LINT pins. */
  912                 lapic_set_lvt_mode(APIC_ID_ALL, APIC_LVT_LINT0,
  913                     APIC_LVT_DM_EXTINT);
  914                 lapic_set_lvt_mode(APIC_ID_ALL, APIC_LVT_LINT1, APIC_LVT_DM_NMI);
  915 
  916                 /* Configure I/O APIC pins. */
  917                 mptable_parse_default_config_ints();
  918         } else
  919                 mptable_walk_table(mptable_parse_ints_handler, NULL);
  920 }
  921 
  922 #ifdef MPTABLE_FORCE_HTT
  923 /*
  924  * Perform a hyperthreading "fix-up" to enumerate any logical CPU's
  925  * that aren't already listed in the table.
  926  *
  927  * XXX: We assume that all of the physical CPUs in the
  928  * system have the same number of logical CPUs.
  929  *
  930  * XXX: We assume that APIC ID's are allocated such that
  931  * the APIC ID's for a physical processor are aligned
  932  * with the number of logical CPU's in the processor.
  933  */
  934 static void
  935 mptable_hyperthread_fixup(u_int id_mask)
  936 {
  937         u_int i, id, logical_cpus;
  938 
  939         /* Nothing to do if there is no HTT support. */
  940         if ((cpu_feature & CPUID_HTT) == 0)
  941                 return;
  942         logical_cpus = (cpu_procinfo & CPUID_HTT_CORES) >> 16;
  943         if (logical_cpus <= 1)
  944                 return;
  945 
  946         /*
  947          * For each APIC ID of a CPU that is set in the mask,
  948          * scan the other candidate APIC ID's for this
  949          * physical processor.  If any of those ID's are
  950          * already in the table, then kill the fixup.
  951          */
  952         for (id = 0; id <= MAX_LAPIC_ID; id++) {
  953                 if ((id_mask & 1 << id) == 0)
  954                         continue;
  955                 /* First, make sure we are on a logical_cpus boundary. */
  956                 if (id % logical_cpus != 0)
  957                         return;
  958                 for (i = id + 1; i < id + logical_cpus; i++)
  959                         if ((id_mask & 1 << i) != 0)
  960                                 return;
  961         }
  962 
  963         /*
  964          * Ok, the ID's checked out, so perform the fixup by
  965          * adding the logical CPUs.
  966          */
  967         while ((id = ffs(id_mask)) != 0) {
  968                 id--;
  969                 for (i = id + 1; i < id + logical_cpus; i++) {
  970                         if (bootverbose)
  971                                 printf(
  972                         "MPTable: Adding logical CPU %d from main CPU %d\n",
  973                                     i, id);
  974                         lapic_create(i, 0);
  975                 }
  976                 id_mask &= ~(1 << id);
  977         }
  978 }
  979 #endif /* MPTABLE_FORCE_HTT */
  980 
  981 /*
  982  * Support code for routing PCI interrupts using the MP Table.
  983  */
  984 static void
  985 mptable_pci_setup(void)
  986 {
  987         int i;
  988 
  989         /*
  990          * Find the first pci bus and call it 0.  Panic if pci0 is not
  991          * bus zero and there are multiple PCI busses.
  992          */
  993         for (i = 0; i <= mptable_maxbusid; i++)
  994                 if (busses[i].bus_type == PCI) {
  995                         if (pci0 == -1)
  996                                 pci0 = i;
  997                         else if (pci0 != 0)
  998                                 panic(
  999                 "MPTable contains multiple PCI busses but no PCI bus 0");
 1000                 }
 1001 }
 1002 
 1003 static void
 1004 mptable_pci_probe_table_handler(u_char *entry, void *arg)
 1005 {
 1006         struct pci_probe_table_args *args;
 1007         int_entry_ptr intr;
 1008 
 1009         if (*entry != MPCT_ENTRY_INT)
 1010                 return;
 1011         intr = (int_entry_ptr)entry;
 1012         args = (struct pci_probe_table_args *)arg;
 1013         KASSERT(args->bus <= mptable_maxbusid,
 1014             ("bus %d is too big", args->bus));
 1015         KASSERT(busses[args->bus].bus_type == PCI, ("probing for non-PCI bus"));
 1016         if (intr->src_bus_id == args->bus)
 1017                 args->found = 1;
 1018 }
 1019 
 1020 int
 1021 mptable_pci_probe_table(int bus)
 1022 {
 1023         struct pci_probe_table_args args;
 1024 
 1025         if (bus < 0)
 1026                 return (EINVAL);
 1027         if (mpct == NULL || pci0 == -1 || pci0 + bus > mptable_maxbusid)
 1028                 return (ENXIO);
 1029         if (busses[pci0 + bus].bus_type != PCI)
 1030                 return (ENXIO);
 1031         args.bus = pci0 + bus;
 1032         args.found = 0;
 1033         mptable_walk_table(mptable_pci_probe_table_handler, &args);
 1034         if (args.found == 0)
 1035                 return (ENXIO);
 1036         return (0);
 1037 }
 1038 
 1039 static void
 1040 mptable_pci_route_interrupt_handler(u_char *entry, void *arg)
 1041 {
 1042         struct pci_route_interrupt_args *args;
 1043         int_entry_ptr intr;
 1044         int vector;
 1045 
 1046         if (*entry != MPCT_ENTRY_INT)
 1047                 return;
 1048         intr = (int_entry_ptr)entry;
 1049         args = (struct pci_route_interrupt_args *)arg;
 1050         if (intr->src_bus_id != args->bus || intr->src_bus_irq != args->irq)
 1051                 return;
 1052 
 1053         /* Make sure the APIC maps to a known APIC. */
 1054         KASSERT(ioapics[intr->dst_apic_id] != NULL,
 1055             ("No I/O APIC %d to route interrupt to", intr->dst_apic_id));
 1056 
 1057         /*
 1058          * Look up the vector for this APIC / pin combination.  If we
 1059          * have previously matched an entry for this PCI IRQ but it
 1060          * has the same vector as this entry, just return.  Otherwise,
 1061          * we use the vector for this APIC / pin combination.
 1062          */
 1063         vector = ioapic_get_vector(ioapics[intr->dst_apic_id],
 1064             intr->dst_apic_int);
 1065         if (args->vector == vector)
 1066                 return;
 1067         KASSERT(args->vector == -1,
 1068             ("Multiple IRQs for PCI interrupt %d.%d.INT%c: %d and %d\n",
 1069             args->bus, args->irq >> 2, 'A' + (args->irq & 0x3), args->vector,
 1070             vector));
 1071         args->vector = vector;
 1072 }
 1073 
 1074 int
 1075 mptable_pci_route_interrupt(device_t pcib, device_t dev, int pin)
 1076 {
 1077         struct pci_route_interrupt_args args;
 1078         int slot;
 1079 
 1080         /* Like ACPI, pin numbers are 0-3, not 1-4. */
 1081         pin--;
 1082         KASSERT(pci0 != -1, ("do not know how to route PCI interrupts"));
 1083         args.bus = pci_get_bus(dev) + pci0;
 1084         slot = pci_get_slot(dev);
 1085 
 1086         /*
 1087          * PCI interrupt entries in the MP Table encode both the slot and
 1088          * pin into the IRQ with the pin being the two least significant
 1089          * bits, the slot being the next five bits, and the most significant
 1090          * bit being reserved.
 1091          */
 1092         args.irq = slot << 2 | pin;
 1093         args.vector = -1;
 1094         mptable_walk_table(mptable_pci_route_interrupt_handler, &args);
 1095         if (args.vector < 0) {
 1096                 device_printf(pcib, "unable to route slot %d INT%c\n", slot,
 1097                     'A' + pin);
 1098                 return (PCI_INVALID_IRQ);
 1099         }
 1100         if (bootverbose)
 1101                 device_printf(pcib, "slot %d INT%c routed to irq %d\n", slot,
 1102                     'A' + pin, args.vector);
 1103         return (args.vector);
 1104 }
 1105 
 1106 #ifdef NEW_PCIB
 1107 struct host_res_args {
 1108         struct mptable_hostb_softc *sc;
 1109         device_t dev;
 1110         u_char  bus;
 1111 };
 1112 
 1113 /*
 1114  * Initialize a Host-PCI bridge so it can restrict resource allocation
 1115  * requests to the resources it actually decodes according to MP
 1116  * config table extended entries.
 1117  */
 1118 static void
 1119 mptable_host_res_handler(ext_entry_ptr entry, void *arg)
 1120 {
 1121         struct host_res_args *args;
 1122         cbasm_entry_ptr cbasm;
 1123         sas_entry_ptr sas;
 1124         const char *name;
 1125         uint64_t start, end;
 1126         int error, *flagp, flags, type;
 1127 
 1128         args = arg;
 1129         switch (entry->type) {
 1130         case MPCT_EXTENTRY_SAS:
 1131                 sas = (sas_entry_ptr)entry;
 1132                 if (sas->bus_id != args->bus)
 1133                         break;
 1134                 switch (sas->address_type) {
 1135                 case SASENTRY_TYPE_IO:
 1136                         type = SYS_RES_IOPORT;
 1137                         flags = 0;
 1138                         break;
 1139                 case SASENTRY_TYPE_MEMORY:
 1140                         type = SYS_RES_MEMORY;
 1141                         flags = 0;
 1142                         break;
 1143                 case SASENTRY_TYPE_PREFETCH:
 1144                         type = SYS_RES_MEMORY;
 1145                         flags = RF_PREFETCHABLE;
 1146                         break;
 1147                 default:
 1148                         printf(
 1149             "MPTable: Unknown systems address space type for bus %u: %d\n",
 1150                             sas->bus_id, sas->address_type);
 1151                         return;
 1152                 }
 1153                 start = sas->address_base;
 1154                 end = sas->address_base + sas->address_length - 1;
 1155 #ifdef __i386__
 1156                 if (start > ULONG_MAX) {
 1157                         device_printf(args->dev,
 1158                             "Ignoring %d range above 4GB (%#jx-%#jx)\n",
 1159                             type, (uintmax_t)start, (uintmax_t)end);
 1160                         break;
 1161                 }
 1162                 if (end > ULONG_MAX) {
 1163                         device_printf(args->dev,
 1164                     "Truncating end of %d range above 4GB (%#jx-%#jx)\n",
 1165                             type, (uintmax_t)start, (uintmax_t)end);
 1166                         end = ULONG_MAX;
 1167                 }
 1168 #endif
 1169                 error = pcib_host_res_decodes(&args->sc->sc_host_res, type,
 1170                     start, end, flags);
 1171                 if (error)
 1172                         panic("Failed to manage %d range (%#jx-%#jx): %d",
 1173                             type, (uintmax_t)start, (uintmax_t)end, error);
 1174                 break;
 1175         case MPCT_EXTENTRY_CBASM:
 1176                 cbasm = (cbasm_entry_ptr)entry;
 1177                 if (cbasm->bus_id != args->bus)
 1178                         break;
 1179                 switch (cbasm->predefined_range) {
 1180                 case CBASMENTRY_RANGE_ISA_IO:
 1181                         flagp = &args->sc->sc_decodes_isa_io;
 1182                         name = "ISA I/O";
 1183                         break;
 1184                 case CBASMENTRY_RANGE_VGA_IO:
 1185                         flagp = &args->sc->sc_decodes_vga_io;
 1186                         name = "VGA I/O";
 1187                         break;
 1188                 default:
 1189                         printf(
 1190     "MPTable: Unknown compatiblity address space range for bus %u: %d\n",
 1191                             cbasm->bus_id, cbasm->predefined_range);
 1192                         return;
 1193                 }
 1194                 if (*flagp != 0)
 1195                         printf(
 1196                     "MPTable: Duplicate compatibility %s range for bus %u\n",
 1197                             name, cbasm->bus_id);
 1198                 switch (cbasm->address_mod) {
 1199                 case CBASMENTRY_ADDRESS_MOD_ADD:
 1200                         *flagp = 1;
 1201                         if (bootverbose)
 1202                                 device_printf(args->dev, "decoding %s ports\n",
 1203                                     name);
 1204                         break;
 1205                 case CBASMENTRY_ADDRESS_MOD_SUBTRACT:
 1206                         *flagp = -1;
 1207                         if (bootverbose)
 1208                                 device_printf(args->dev,
 1209                                     "not decoding %s ports\n", name);
 1210                         break;
 1211                 default:
 1212                         printf(
 1213             "MPTable: Unknown compatibility address space modifier: %u\n",
 1214                             cbasm->address_mod);
 1215                         break;
 1216                 }
 1217                 break;
 1218         }
 1219 }
 1220 
 1221 void
 1222 mptable_pci_host_res_init(device_t pcib)
 1223 {
 1224         struct host_res_args args;
 1225 
 1226         KASSERT(pci0 != -1, ("do not know how to map PCI bus IDs"));
 1227         args.bus = pci_get_bus(pcib) + pci0;
 1228         args.dev = pcib;
 1229         args.sc = device_get_softc(pcib);
 1230         if (pcib_host_res_init(pcib, &args.sc->sc_host_res) != 0)
 1231                 panic("failed to init hostb resources");
 1232         mptable_walk_extended_table(mptable_host_res_handler, &args);
 1233 }
 1234 #endif

Cache object: 061d9dfbf7b880f23b7b131733c49f3f


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.