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