xref: /freebsd/sys/x86/x86/mptable.c (revision 38a52bd3)
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