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