madt.c (167247) | madt.c (167814) |
---|---|
1/*- 2 * Copyright (c) 2003 John Baldwin <jhb@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 14 unchanged lines hidden (view full) --- 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2003 John Baldwin <jhb@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 14 unchanged lines hidden (view full) --- 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30#include <sys/cdefs.h> |
31__FBSDID("$FreeBSD: head/sys/i386/acpica/madt.c 167247 2007-03-05 20:35:17Z jhb $"); | 31__FBSDID("$FreeBSD: head/sys/i386/acpica/madt.c 167814 2007-03-22 18:16:43Z jkim $"); |
32 33#include <sys/param.h> 34#include <sys/systm.h> 35#include <sys/bus.h> 36#include <sys/kernel.h> 37#include <sys/malloc.h> 38#include <sys/smp.h> 39 --- 11 unchanged lines hidden (view full) --- 51#include <contrib/dev/acpica/acpi.h> 52#include <contrib/dev/acpica/actables.h> 53#include <dev/acpica/acpivar.h> 54#include <dev/pci/pcivar.h> 55 56#define NIOAPICS 32 /* Max number of I/O APICs */ 57#define NLAPICS 32 /* Max number of local APICs */ 58 | 32 33#include <sys/param.h> 34#include <sys/systm.h> 35#include <sys/bus.h> 36#include <sys/kernel.h> 37#include <sys/malloc.h> 38#include <sys/smp.h> 39 --- 11 unchanged lines hidden (view full) --- 51#include <contrib/dev/acpica/acpi.h> 52#include <contrib/dev/acpica/actables.h> 53#include <dev/acpica/acpivar.h> 54#include <dev/pci/pcivar.h> 55 56#define NIOAPICS 32 /* Max number of I/O APICs */ 57#define NLAPICS 32 /* Max number of local APICs */ 58 |
59typedef void madt_entry_handler(APIC_HEADER *entry, void *arg); | 59typedef void madt_entry_handler(ACPI_SUBTABLE_HEADER *entry, void *arg); |
60 61/* These two arrays are indexed by APIC IDs. */ 62struct ioapic_info { 63 void *io_apic; 64 UINT32 io_vector; 65} ioapics[NIOAPICS]; 66 67struct lapic_info { 68 u_int la_enabled:1; 69 u_int la_acpi_id:8; 70} lapics[NLAPICS]; 71 72static int madt_found_sci_override; | 60 61/* These two arrays are indexed by APIC IDs. */ 62struct ioapic_info { 63 void *io_apic; 64 UINT32 io_vector; 65} ioapics[NIOAPICS]; 66 67struct lapic_info { 68 u_int la_enabled:1; 69 u_int la_acpi_id:8; 70} lapics[NLAPICS]; 71 72static int madt_found_sci_override; |
73static MULTIPLE_APIC_TABLE *madt; | 73static ACPI_TABLE_MADT *madt; |
74static vm_paddr_t madt_physaddr; 75static vm_offset_t madt_length; 76 77MALLOC_DEFINE(M_MADT, "madt_table", "ACPI MADT Table Items"); 78 | 74static vm_paddr_t madt_physaddr; 75static vm_offset_t madt_length; 76 77MALLOC_DEFINE(M_MADT, "madt_table", "ACPI MADT Table Items"); 78 |
79static enum intr_polarity interrupt_polarity(UINT16 Polarity, UINT8 Source); 80static enum intr_trigger interrupt_trigger(UINT16 TriggerMode, UINT8 Source); | 79static enum intr_polarity interrupt_polarity(UINT16 IntiFlags, UINT8 Source); 80static enum intr_trigger interrupt_trigger(UINT16 IntiFlags, UINT8 Source); |
81static int madt_find_cpu(u_int acpi_id, u_int *apic_id); 82static int madt_find_interrupt(int intr, void **apic, u_int *pin); 83static void *madt_map(vm_paddr_t pa, int offset, vm_offset_t length); 84static void *madt_map_table(vm_paddr_t pa, int offset, const char *sig); | 81static int madt_find_cpu(u_int acpi_id, u_int *apic_id); 82static int madt_find_interrupt(int intr, void **apic, u_int *pin); 83static void *madt_map(vm_paddr_t pa, int offset, vm_offset_t length); 84static void *madt_map_table(vm_paddr_t pa, int offset, const char *sig); |
85static void madt_parse_apics(APIC_HEADER *entry, void *arg); 86static void madt_parse_interrupt_override(MADT_INTERRUPT_OVERRIDE *intr); 87static void madt_parse_ints(APIC_HEADER *entry, void *arg __unused); 88static void madt_parse_local_nmi(MADT_LOCAL_APIC_NMI *nmi); 89static void madt_parse_nmi(MADT_NMI_SOURCE *nmi); | 85static void madt_parse_apics(ACPI_SUBTABLE_HEADER *entry, void *arg); 86static void madt_parse_interrupt_override( 87 ACPI_MADT_INTERRUPT_OVERRIDE *intr); 88static void madt_parse_ints(ACPI_SUBTABLE_HEADER *entry, 89 void *arg __unused); 90static void madt_parse_local_nmi(ACPI_MADT_LOCAL_APIC_NMI *nmi); 91static void madt_parse_nmi(ACPI_MADT_NMI_SOURCE *nmi); |
90static int madt_probe(void); 91static int madt_probe_cpus(void); | 92static int madt_probe(void); 93static int madt_probe_cpus(void); |
92static void madt_probe_cpus_handler(APIC_HEADER *entry, void *arg __unused); | 94static void madt_probe_cpus_handler(ACPI_SUBTABLE_HEADER *entry, 95 void *arg __unused); |
93static int madt_probe_table(vm_paddr_t address); 94static void madt_register(void *dummy); 95static int madt_setup_local(void); 96static int madt_setup_io(void); 97static void madt_unmap(void *data, vm_offset_t length); 98static void madt_unmap_table(void *table); 99static void madt_walk_table(madt_entry_handler *handler, void *arg); 100 --- 55 unchanged lines hidden (view full) --- 156static void * 157madt_map_table(vm_paddr_t pa, int offset, const char *sig) 158{ 159 ACPI_TABLE_HEADER *header; 160 vm_offset_t length; 161 void *table; 162 163 header = madt_map(pa, offset, sizeof(ACPI_TABLE_HEADER)); | 96static int madt_probe_table(vm_paddr_t address); 97static void madt_register(void *dummy); 98static int madt_setup_local(void); 99static int madt_setup_io(void); 100static void madt_unmap(void *data, vm_offset_t length); 101static void madt_unmap_table(void *table); 102static void madt_walk_table(madt_entry_handler *handler, void *arg); 103 --- 55 unchanged lines hidden (view full) --- 159static void * 160madt_map_table(vm_paddr_t pa, int offset, const char *sig) 161{ 162 ACPI_TABLE_HEADER *header; 163 vm_offset_t length; 164 void *table; 165 166 header = madt_map(pa, offset, sizeof(ACPI_TABLE_HEADER)); |
164 if (strncmp(header->Signature, sig, 4) != 0) { | 167 if (strncmp(header->Signature, sig, ACPI_NAME_SIZE) != 0) { |
165 madt_unmap(header, sizeof(ACPI_TABLE_HEADER)); 166 return (NULL); 167 } 168 length = header->Length; 169 madt_unmap(header, sizeof(ACPI_TABLE_HEADER)); 170 table = madt_map(pa, offset, length); | 168 madt_unmap(header, sizeof(ACPI_TABLE_HEADER)); 169 return (NULL); 170 } 171 length = header->Length; 172 madt_unmap(header, sizeof(ACPI_TABLE_HEADER)); 173 table = madt_map(pa, offset, length); |
171 if (ACPI_FAILURE(AcpiTbVerifyTableChecksum(table))) { | 174 if (ACPI_FAILURE(AcpiTbChecksum(table, length))) { |
172 if (bootverbose) 173 printf("MADT: Failed checksum for table %s\n", sig); 174 madt_unmap(table, length); 175 return (NULL); 176 } 177 return (table); 178} 179 --- 7 unchanged lines hidden (view full) --- 187} 188 189/* 190 * Look for an ACPI Multiple APIC Description Table ("APIC") 191 */ 192static int 193madt_probe(void) 194{ | 175 if (bootverbose) 176 printf("MADT: Failed checksum for table %s\n", sig); 177 madt_unmap(table, length); 178 return (NULL); 179 } 180 return (table); 181} 182 --- 7 unchanged lines hidden (view full) --- 190} 191 192/* 193 * Look for an ACPI Multiple APIC Description Table ("APIC") 194 */ 195static int 196madt_probe(void) 197{ |
195 ACPI_POINTER rsdp_ptr; 196 RSDP_DESCRIPTOR *rsdp; 197 RSDT_DESCRIPTOR *rsdt; 198 XSDT_DESCRIPTOR *xsdt; | 198 ACPI_PHYSICAL_ADDRESS rsdp_ptr; 199 ACPI_TABLE_RSDP *rsdp; 200 ACPI_TABLE_RSDT *rsdt; 201 ACPI_TABLE_XSDT *xsdt; |
199 int i, count; 200 201 if (resource_disabled("acpi", 0)) 202 return (ENXIO); 203 204 /* 205 * Map in the RSDP. Since ACPI uses AcpiOsMapMemory() which in turn 206 * calls pmap_mapbios() to find the RSDP, we assume that we can use 207 * pmap_mapbios() to map the RSDP. 208 */ | 202 int i, count; 203 204 if (resource_disabled("acpi", 0)) 205 return (ENXIO); 206 207 /* 208 * Map in the RSDP. Since ACPI uses AcpiOsMapMemory() which in turn 209 * calls pmap_mapbios() to find the RSDP, we assume that we can use 210 * pmap_mapbios() to map the RSDP. 211 */ |
209 if (AcpiOsGetRootPointer(ACPI_LOGICAL_ADDRESSING, &rsdp_ptr) != AE_OK) | 212 if ((rsdp_ptr = AcpiOsGetRootPointer()) == 0) |
210 return (ENXIO); | 213 return (ENXIO); |
211#ifdef __i386__ 212 KASSERT(rsdp_ptr.Pointer.Physical < KERNLOAD, ("RSDP too high")); 213#endif 214 rsdp = pmap_mapbios(rsdp_ptr.Pointer.Physical, sizeof(RSDP_DESCRIPTOR)); | 214 rsdp = pmap_mapbios(rsdp_ptr, sizeof(ACPI_TABLE_RSDP)); |
215 if (rsdp == NULL) { 216 if (bootverbose) 217 printf("MADT: Failed to map RSDP\n"); 218 return (ENXIO); 219 } 220 221 /* 222 * For ACPI >= 2.0, use the XSDT if it is available. 223 * Otherwise, use the RSDT. We map the XSDT or RSDT at page 1 224 * in the crashdump area. Page 0 is used to map in the 225 * headers of candidate ACPI tables. 226 */ 227 if (rsdp->Revision >= 2 && rsdp->XsdtPhysicalAddress != 0) { 228 /* 229 * AcpiOsGetRootPointer only verifies the checksum for 230 * the version 1.0 portion of the RSDP. Version 2.0 has 231 * an additional checksum that we verify first. 232 */ | 215 if (rsdp == NULL) { 216 if (bootverbose) 217 printf("MADT: Failed to map RSDP\n"); 218 return (ENXIO); 219 } 220 221 /* 222 * For ACPI >= 2.0, use the XSDT if it is available. 223 * Otherwise, use the RSDT. We map the XSDT or RSDT at page 1 224 * in the crashdump area. Page 0 is used to map in the 225 * headers of candidate ACPI tables. 226 */ 227 if (rsdp->Revision >= 2 && rsdp->XsdtPhysicalAddress != 0) { 228 /* 229 * AcpiOsGetRootPointer only verifies the checksum for 230 * the version 1.0 portion of the RSDP. Version 2.0 has 231 * an additional checksum that we verify first. 232 */ |
233 if (AcpiTbGenerateChecksum(rsdp, ACPI_RSDP_XCHECKSUM_LENGTH)) { | 233 if (AcpiTbChecksum((UINT8 *)rsdp, ACPI_RSDP_XCHECKSUM_LENGTH)) { |
234 if (bootverbose) 235 printf("MADT: RSDP failed extended checksum\n"); 236 return (ENXIO); 237 } | 234 if (bootverbose) 235 printf("MADT: RSDP failed extended checksum\n"); 236 return (ENXIO); 237 } |
238 xsdt = madt_map_table(rsdp->XsdtPhysicalAddress, 1, XSDT_SIG); | 238 xsdt = madt_map_table(rsdp->XsdtPhysicalAddress, 1, 239 ACPI_SIG_XSDT); |
239 if (xsdt == NULL) { 240 if (bootverbose) 241 printf("MADT: Failed to map XSDT\n"); 242 return (ENXIO); 243 } | 240 if (xsdt == NULL) { 241 if (bootverbose) 242 printf("MADT: Failed to map XSDT\n"); 243 return (ENXIO); 244 } |
244 count = (xsdt->Length - sizeof(ACPI_TABLE_HEADER)) / | 245 count = (xsdt->Header.Length - sizeof(ACPI_TABLE_HEADER)) / |
245 sizeof(UINT64); 246 for (i = 0; i < count; i++) 247 if (madt_probe_table(xsdt->TableOffsetEntry[i])) 248 break; 249 madt_unmap_table(xsdt); 250 } else { | 246 sizeof(UINT64); 247 for (i = 0; i < count; i++) 248 if (madt_probe_table(xsdt->TableOffsetEntry[i])) 249 break; 250 madt_unmap_table(xsdt); 251 } else { |
251 rsdt = madt_map_table(rsdp->RsdtPhysicalAddress, 1, RSDT_SIG); | 252 rsdt = madt_map_table(rsdp->RsdtPhysicalAddress, 1, 253 ACPI_SIG_RSDT); |
252 if (rsdt == NULL) { 253 if (bootverbose) 254 printf("MADT: Failed to map RSDT\n"); 255 return (ENXIO); 256 } | 254 if (rsdt == NULL) { 255 if (bootverbose) 256 printf("MADT: Failed to map RSDT\n"); 257 return (ENXIO); 258 } |
257 count = (rsdt->Length - sizeof(ACPI_TABLE_HEADER)) / | 259 count = (rsdt->Header.Length - sizeof(ACPI_TABLE_HEADER)) / |
258 sizeof(UINT32); 259 for (i = 0; i < count; i++) 260 if (madt_probe_table(rsdt->TableOffsetEntry[i])) 261 break; 262 madt_unmap_table(rsdt); 263 } | 260 sizeof(UINT32); 261 for (i = 0; i < count; i++) 262 if (madt_probe_table(rsdt->TableOffsetEntry[i])) 263 break; 264 madt_unmap_table(rsdt); 265 } |
264 pmap_unmapbios((vm_offset_t)rsdp, sizeof(RSDP_DESCRIPTOR)); | 266 pmap_unmapbios((vm_offset_t)rsdp, sizeof(ACPI_TABLE_RSDP)); |
265 if (madt_physaddr == 0) { 266 if (bootverbose) 267 printf("MADT: No MADT table found\n"); 268 return (ENXIO); 269 } 270 if (bootverbose) 271 printf("MADT: Found table at 0x%jx\n", 272 (uintmax_t)madt_physaddr); 273 274 /* 275 * Verify that we can map the full table and that its checksum is 276 * correct, etc. 277 */ | 267 if (madt_physaddr == 0) { 268 if (bootverbose) 269 printf("MADT: No MADT table found\n"); 270 return (ENXIO); 271 } 272 if (bootverbose) 273 printf("MADT: Found table at 0x%jx\n", 274 (uintmax_t)madt_physaddr); 275 276 /* 277 * Verify that we can map the full table and that its checksum is 278 * correct, etc. 279 */ |
278 madt = madt_map_table(madt_physaddr, 0, APIC_SIG); | 280 madt = madt_map_table(madt_physaddr, 0, ACPI_SIG_MADT); |
279 if (madt == NULL) 280 return (ENXIO); 281 madt_unmap_table(madt); 282 madt = NULL; 283 284 return (0); 285} 286 --- 11 unchanged lines hidden (view full) --- 298 printf("MADT: Failed to map table at 0x%jx\n", 299 (uintmax_t)address); 300 return (0); 301 } 302 if (bootverbose) 303 printf("Table '%.4s' at 0x%jx\n", table->Signature, 304 (uintmax_t)address); 305 | 281 if (madt == NULL) 282 return (ENXIO); 283 madt_unmap_table(madt); 284 madt = NULL; 285 286 return (0); 287} 288 --- 11 unchanged lines hidden (view full) --- 300 printf("MADT: Failed to map table at 0x%jx\n", 301 (uintmax_t)address); 302 return (0); 303 } 304 if (bootverbose) 305 printf("Table '%.4s' at 0x%jx\n", table->Signature, 306 (uintmax_t)address); 307 |
306 if (strncmp(table->Signature, APIC_SIG, 4) != 0) { | 308 if (strncmp(table->Signature, ACPI_SIG_MADT, ACPI_NAME_SIZE) != 0) { |
307 madt_unmap(table, sizeof(ACPI_TABLE_HEADER)); 308 return (0); 309 } 310 madt_physaddr = address; 311 madt_length = table->Length; 312 madt_unmap(table, sizeof(ACPI_TABLE_HEADER)); 313 return (1); 314} 315 316/* 317 * Run through the MP table enumerating CPUs. 318 */ 319static int 320madt_probe_cpus(void) 321{ 322 | 309 madt_unmap(table, sizeof(ACPI_TABLE_HEADER)); 310 return (0); 311 } 312 madt_physaddr = address; 313 madt_length = table->Length; 314 madt_unmap(table, sizeof(ACPI_TABLE_HEADER)); 315 return (1); 316} 317 318/* 319 * Run through the MP table enumerating CPUs. 320 */ 321static int 322madt_probe_cpus(void) 323{ 324 |
323 madt = madt_map_table(madt_physaddr, 0, APIC_SIG); | 325 madt = madt_map_table(madt_physaddr, 0, ACPI_SIG_MADT); |
324 KASSERT(madt != NULL, ("Unable to re-map MADT")); 325 madt_walk_table(madt_probe_cpus_handler, NULL); 326 madt_unmap_table(madt); 327 madt = NULL; 328 return (0); 329} 330 331/* 332 * Initialize the local APIC on the BSP. 333 */ 334static int 335madt_setup_local(void) 336{ 337 338 madt = pmap_mapbios(madt_physaddr, madt_length); | 326 KASSERT(madt != NULL, ("Unable to re-map MADT")); 327 madt_walk_table(madt_probe_cpus_handler, NULL); 328 madt_unmap_table(madt); 329 madt = NULL; 330 return (0); 331} 332 333/* 334 * Initialize the local APIC on the BSP. 335 */ 336static int 337madt_setup_local(void) 338{ 339 340 madt = pmap_mapbios(madt_physaddr, madt_length); |
339 lapic_init(madt->LocalApicAddress); | 341 lapic_init(madt->Address); |
340 printf("ACPI APIC Table: <%.*s %.*s>\n", | 342 printf("ACPI APIC Table: <%.*s %.*s>\n", |
341 (int)sizeof(madt->OemId), madt->OemId, 342 (int)sizeof(madt->OemTableId), madt->OemTableId); | 343 (int)sizeof(madt->Header.OemId), madt->Header.OemId, 344 (int)sizeof(madt->Header.OemTableId), madt->Header.OemTableId); |
343 344 /* 345 * We ignore 64-bit local APIC override entries. Should we 346 * perhaps emit a warning here if we find one? 347 */ 348 return (0); 349} 350 --- 22 unchanged lines hidden (view full) --- 373 /* Second, we run through the table tweaking interrupt sources. */ 374 madt_walk_table(madt_parse_ints, NULL); 375 376 /* 377 * If there was not an explicit override entry for the SCI, 378 * force it to use level trigger and active-low polarity. 379 */ 380 if (!madt_found_sci_override) { | 345 346 /* 347 * We ignore 64-bit local APIC override entries. Should we 348 * perhaps emit a warning here if we find one? 349 */ 350 return (0); 351} 352 --- 22 unchanged lines hidden (view full) --- 375 /* Second, we run through the table tweaking interrupt sources. */ 376 madt_walk_table(madt_parse_ints, NULL); 377 378 /* 379 * If there was not an explicit override entry for the SCI, 380 * force it to use level trigger and active-low polarity. 381 */ 382 if (!madt_found_sci_override) { |
381 if (madt_find_interrupt(AcpiGbl_FADT->SciInt, &ioapic, &pin) 382 != 0) 383 printf("MADT: Could not find APIC for SCI IRQ %d\n", 384 AcpiGbl_FADT->SciInt); | 383 if (madt_find_interrupt(AcpiGbl_FADT.SciInterrupt, &ioapic, 384 &pin) != 0) 385 printf("MADT: Could not find APIC for SCI IRQ %u\n", 386 AcpiGbl_FADT.SciInterrupt); |
385 else { 386 printf( 387 "MADT: Forcing active-low polarity and level trigger for SCI\n"); 388 ioapic_set_polarity(ioapic, pin, INTR_POLARITY_LOW); 389 ioapic_set_triggermode(ioapic, pin, INTR_TRIGGER_LEVEL); 390 } 391 } 392 --- 17 unchanged lines hidden (view full) --- 410SYSINIT(madt_register, SI_SUB_CPU - 1, SI_ORDER_FIRST, madt_register, NULL) 411 412/* 413 * Call the handler routine for each entry in the MADT table. 414 */ 415static void 416madt_walk_table(madt_entry_handler *handler, void *arg) 417{ | 387 else { 388 printf( 389 "MADT: Forcing active-low polarity and level trigger for SCI\n"); 390 ioapic_set_polarity(ioapic, pin, INTR_POLARITY_LOW); 391 ioapic_set_triggermode(ioapic, pin, INTR_TRIGGER_LEVEL); 392 } 393 } 394 --- 17 unchanged lines hidden (view full) --- 412SYSINIT(madt_register, SI_SUB_CPU - 1, SI_ORDER_FIRST, madt_register, NULL) 413 414/* 415 * Call the handler routine for each entry in the MADT table. 416 */ 417static void 418madt_walk_table(madt_entry_handler *handler, void *arg) 419{ |
418 APIC_HEADER *entry; | 420 ACPI_SUBTABLE_HEADER *entry; |
419 u_char *p, *end; 420 | 421 u_char *p, *end; 422 |
421 end = (u_char *)(madt) + madt->Length; | 423 end = (u_char *)(madt) + madt->Header.Length; |
422 for (p = (u_char *)(madt + 1); p < end; ) { | 424 for (p = (u_char *)(madt + 1); p < end; ) { |
423 entry = (APIC_HEADER *)p; | 425 entry = (ACPI_SUBTABLE_HEADER *)p; |
424 handler(entry, arg); 425 p += entry->Length; 426 } 427} 428 429static void | 426 handler(entry, arg); 427 p += entry->Length; 428 } 429} 430 431static void |
430madt_probe_cpus_handler(APIC_HEADER *entry, void *arg) | 432madt_probe_cpus_handler(ACPI_SUBTABLE_HEADER *entry, void *arg) |
431{ | 433{ |
432 MADT_PROCESSOR_APIC *proc; | 434 ACPI_MADT_LOCAL_APIC *proc; |
433 struct lapic_info *la; 434 435 switch (entry->Type) { | 435 struct lapic_info *la; 436 437 switch (entry->Type) { |
436 case APIC_PROCESSOR: | 438 case ACPI_MADT_TYPE_LOCAL_APIC: |
437 /* 438 * The MADT does not include a BSP flag, so we have to 439 * let the MP code figure out which CPU is the BSP on 440 * its own. 441 */ | 439 /* 440 * The MADT does not include a BSP flag, so we have to 441 * let the MP code figure out which CPU is the BSP on 442 * its own. 443 */ |
442 proc = (MADT_PROCESSOR_APIC *)entry; | 444 proc = (ACPI_MADT_LOCAL_APIC *)entry; |
443 if (bootverbose) | 445 if (bootverbose) |
444 printf("MADT: Found CPU APIC ID %d ACPI ID %d: %s\n", 445 proc->LocalApicId, proc->ProcessorId, 446 proc->ProcessorEnabled ? "enabled" : "disabled"); 447 if (!proc->ProcessorEnabled) | 446 printf("MADT: Found CPU APIC ID %u ACPI ID %u: %s\n", 447 proc->Id, proc->ProcessorId, 448 (proc->LapicFlags & ACPI_MADT_ENABLED) ? 449 "enabled" : "disabled"); 450 if (!(proc->LapicFlags & ACPI_MADT_ENABLED)) |
448 break; | 451 break; |
449 if (proc->LocalApicId >= NLAPICS) 450 panic("%s: CPU ID %d too high", __func__, 451 proc->LocalApicId); 452 la = &lapics[proc->LocalApicId]; | 452 if (proc->Id >= NLAPICS) 453 panic("%s: CPU ID %u too high", __func__, proc->Id); 454 la = &lapics[proc->Id]; |
453 KASSERT(la->la_enabled == 0, | 455 KASSERT(la->la_enabled == 0, |
454 ("Duplicate local APIC ID %d", proc->LocalApicId)); | 456 ("Duplicate local APIC ID %u", proc->Id)); |
455 la->la_enabled = 1; 456 la->la_acpi_id = proc->ProcessorId; | 457 la->la_enabled = 1; 458 la->la_acpi_id = proc->ProcessorId; |
457 lapic_create(proc->LocalApicId, 0); | 459 lapic_create(proc->Id, 0); |
458 break; 459 } 460} 461 462 463/* 464 * Add an I/O APIC from an entry in the table. 465 */ 466static void | 460 break; 461 } 462} 463 464 465/* 466 * Add an I/O APIC from an entry in the table. 467 */ 468static void |
467madt_parse_apics(APIC_HEADER *entry, void *arg __unused) | 469madt_parse_apics(ACPI_SUBTABLE_HEADER *entry, void *arg __unused) |
468{ | 470{ |
469 MADT_IO_APIC *apic; | 471 ACPI_MADT_IO_APIC *apic; |
470 471 switch (entry->Type) { | 472 473 switch (entry->Type) { |
472 case APIC_IO: 473 apic = (MADT_IO_APIC *)entry; | 474 case ACPI_MADT_TYPE_IO_APIC: 475 apic = (ACPI_MADT_IO_APIC *)entry; |
474 if (bootverbose) | 476 if (bootverbose) |
475 printf("MADT: Found IO APIC ID %d, Interrupt %d at %p\n", 476 apic->IoApicId, apic->Interrupt, | 477 printf( 478 "MADT: Found IO APIC ID %u, Interrupt %u at %p\n", 479 apic->Id, apic->GlobalIrqBase, |
477 (void *)(uintptr_t)apic->Address); | 480 (void *)(uintptr_t)apic->Address); |
478 if (apic->IoApicId >= NIOAPICS) 479 panic("%s: I/O APIC ID %d too high", __func__, 480 apic->IoApicId); 481 if (ioapics[apic->IoApicId].io_apic != NULL) 482 panic("%s: Double APIC ID %d", __func__, 483 apic->IoApicId); 484 ioapics[apic->IoApicId].io_apic = ioapic_create(apic->Address, 485 apic->IoApicId, apic->Interrupt); 486 ioapics[apic->IoApicId].io_vector = apic->Interrupt; | 481 if (apic->Id >= NIOAPICS) 482 panic("%s: I/O APIC ID %u too high", __func__, 483 apic->Id); 484 if (ioapics[apic->Id].io_apic != NULL) 485 panic("%s: Double APIC ID %u", __func__, apic->Id); 486 ioapics[apic->Id].io_apic = ioapic_create(apic->Address, 487 apic->Id, apic->GlobalIrqBase); 488 ioapics[apic->Id].io_vector = apic->GlobalIrqBase; |
487 break; 488 default: 489 break; 490 } 491} 492 493/* 494 * Determine properties of an interrupt source. Note that for ACPI these 495 * functions are only used for ISA interrupts, so we assume ISA bus values 496 * (Active Hi, Edge Triggered) for conforming values except for the ACPI 497 * SCI for which we use Active Lo, Level Triggered. 498 */ 499static enum intr_polarity | 489 break; 490 default: 491 break; 492 } 493} 494 495/* 496 * Determine properties of an interrupt source. Note that for ACPI these 497 * functions are only used for ISA interrupts, so we assume ISA bus values 498 * (Active Hi, Edge Triggered) for conforming values except for the ACPI 499 * SCI for which we use Active Lo, Level Triggered. 500 */ 501static enum intr_polarity |
500interrupt_polarity(UINT16 Polarity, UINT8 Source) | 502interrupt_polarity(UINT16 IntiFlags, UINT8 Source) |
501{ 502 | 503{ 504 |
503 switch (Polarity) { 504 case POLARITY_CONFORMS: 505 if (Source == AcpiGbl_FADT->SciInt) | 505 switch (IntiFlags & ACPI_MADT_POLARITY_MASK) { 506 case ACPI_MADT_POLARITY_CONFORMS: 507 if (Source == AcpiGbl_FADT.SciInterrupt) |
506 return (INTR_POLARITY_LOW); 507 else 508 return (INTR_POLARITY_HIGH); | 508 return (INTR_POLARITY_LOW); 509 else 510 return (INTR_POLARITY_HIGH); |
509 case POLARITY_ACTIVE_HIGH: | 511 case ACPI_MADT_POLARITY_ACTIVE_HIGH: |
510 return (INTR_POLARITY_HIGH); | 512 return (INTR_POLARITY_HIGH); |
511 case POLARITY_ACTIVE_LOW: | 513 case ACPI_MADT_POLARITY_ACTIVE_LOW: |
512 return (INTR_POLARITY_LOW); 513 default: 514 panic("Bogus Interrupt Polarity"); 515 } 516} 517 518static enum intr_trigger | 514 return (INTR_POLARITY_LOW); 515 default: 516 panic("Bogus Interrupt Polarity"); 517 } 518} 519 520static enum intr_trigger |
519interrupt_trigger(UINT16 TriggerMode, UINT8 Source) | 521interrupt_trigger(UINT16 IntiFlags, UINT8 Source) |
520{ 521 | 522{ 523 |
522 switch (TriggerMode) { 523 case TRIGGER_CONFORMS: 524 if (Source == AcpiGbl_FADT->SciInt) | 524 switch (IntiFlags & ACPI_MADT_TRIGGER_MASK) { 525 case ACPI_MADT_TRIGGER_CONFORMS: 526 if (Source == AcpiGbl_FADT.SciInterrupt) |
525 return (INTR_TRIGGER_LEVEL); 526 else 527 return (INTR_TRIGGER_EDGE); | 527 return (INTR_TRIGGER_LEVEL); 528 else 529 return (INTR_TRIGGER_EDGE); |
528 case TRIGGER_EDGE: | 530 case ACPI_MADT_TRIGGER_EDGE: |
529 return (INTR_TRIGGER_EDGE); | 531 return (INTR_TRIGGER_EDGE); |
530 case TRIGGER_LEVEL: | 532 case ACPI_MADT_TRIGGER_LEVEL: |
531 return (INTR_TRIGGER_LEVEL); 532 default: 533 panic("Bogus Interrupt Trigger Mode"); 534 } 535} 536 537/* 538 * Find the local APIC ID associated with a given ACPI Processor ID. --- 41 unchanged lines hidden (view full) --- 580 intr); 581 return (0); 582} 583 584/* 585 * Parse an interrupt source override for an ISA interrupt. 586 */ 587static void | 533 return (INTR_TRIGGER_LEVEL); 534 default: 535 panic("Bogus Interrupt Trigger Mode"); 536 } 537} 538 539/* 540 * Find the local APIC ID associated with a given ACPI Processor ID. --- 41 unchanged lines hidden (view full) --- 582 intr); 583 return (0); 584} 585 586/* 587 * Parse an interrupt source override for an ISA interrupt. 588 */ 589static void |
588madt_parse_interrupt_override(MADT_INTERRUPT_OVERRIDE *intr) | 590madt_parse_interrupt_override(ACPI_MADT_INTERRUPT_OVERRIDE *intr) |
589{ 590 void *new_ioapic, *old_ioapic; 591 u_int new_pin, old_pin; 592 enum intr_trigger trig; 593 enum intr_polarity pol; 594 char buf[64]; 595 | 591{ 592 void *new_ioapic, *old_ioapic; 593 u_int new_pin, old_pin; 594 enum intr_trigger trig; 595 enum intr_polarity pol; 596 char buf[64]; 597 |
596 if (acpi_quirks & ACPI_Q_MADT_IRQ0 && intr->Source == 0 && 597 intr->Interrupt == 2) { | 598 if (acpi_quirks & ACPI_Q_MADT_IRQ0 && intr->SourceIrq == 0 && 599 intr->GlobalIrq == 2) { |
598 if (bootverbose) 599 printf("MADT: Skipping timer override\n"); 600 return; 601 } 602 if (bootverbose) 603 printf("MADT: Interrupt override: source %u, irq %u\n", | 600 if (bootverbose) 601 printf("MADT: Skipping timer override\n"); 602 return; 603 } 604 if (bootverbose) 605 printf("MADT: Interrupt override: source %u, irq %u\n", |
604 intr->Source, intr->Interrupt); | 606 intr->SourceIrq, intr->GlobalIrq); |
605 KASSERT(intr->Bus == 0, ("bus for interrupt overrides must be zero")); | 607 KASSERT(intr->Bus == 0, ("bus for interrupt overrides must be zero")); |
606 if (madt_find_interrupt(intr->Interrupt, &new_ioapic, 607 &new_pin) != 0) { 608 printf("MADT: Could not find APIC for vector %d (IRQ %d)\n", 609 intr->Interrupt, intr->Source); | 608 if (madt_find_interrupt(intr->GlobalIrq, &new_ioapic, &new_pin) != 0) { 609 printf("MADT: Could not find APIC for vector %u (IRQ %u)\n", 610 intr->GlobalIrq, intr->SourceIrq); |
610 return; 611 } 612 613 /* 614 * Lookup the appropriate trigger and polarity modes for this 615 * entry. 616 */ | 611 return; 612 } 613 614 /* 615 * Lookup the appropriate trigger and polarity modes for this 616 * entry. 617 */ |
617 trig = interrupt_trigger(intr->TriggerMode, intr->Source); 618 pol = interrupt_polarity(intr->Polarity, intr->Source); | 618 trig = interrupt_trigger(intr->IntiFlags, intr->SourceIrq); 619 pol = interrupt_polarity(intr->IntiFlags, intr->SourceIrq); |
619 620 /* 621 * If the SCI is identity mapped but has edge trigger and 622 * active-hi polarity or the force_sci_lo tunable is set, 623 * force it to use level/lo. 624 */ | 620 621 /* 622 * If the SCI is identity mapped but has edge trigger and 623 * active-hi polarity or the force_sci_lo tunable is set, 624 * force it to use level/lo. 625 */ |
625 if (intr->Source == AcpiGbl_FADT->SciInt) { | 626 if (intr->SourceIrq == AcpiGbl_FADT.SciInterrupt) { |
626 madt_found_sci_override = 1; 627 if (getenv_string("hw.acpi.sci.trigger", buf, sizeof(buf))) { 628 if (tolower(buf[0]) == 'e') 629 trig = INTR_TRIGGER_EDGE; 630 else if (tolower(buf[0]) == 'l') 631 trig = INTR_TRIGGER_LEVEL; 632 else 633 panic( --- 12 unchanged lines hidden (view full) --- 646 "Invalid polarity %s: must be 'high' or 'low'", 647 buf); 648 printf("MADT: Forcing SCI to active %s polarity\n", 649 pol == INTR_POLARITY_HIGH ? "high" : "low"); 650 } 651 } 652 653 /* Remap the IRQ if it is mapped to a different interrupt vector. */ | 627 madt_found_sci_override = 1; 628 if (getenv_string("hw.acpi.sci.trigger", buf, sizeof(buf))) { 629 if (tolower(buf[0]) == 'e') 630 trig = INTR_TRIGGER_EDGE; 631 else if (tolower(buf[0]) == 'l') 632 trig = INTR_TRIGGER_LEVEL; 633 else 634 panic( --- 12 unchanged lines hidden (view full) --- 647 "Invalid polarity %s: must be 'high' or 'low'", 648 buf); 649 printf("MADT: Forcing SCI to active %s polarity\n", 650 pol == INTR_POLARITY_HIGH ? "high" : "low"); 651 } 652 } 653 654 /* Remap the IRQ if it is mapped to a different interrupt vector. */ |
654 if (intr->Source != intr->Interrupt) { | 655 if (intr->SourceIrq != intr->GlobalIrq) { |
655 /* 656 * If the SCI is remapped to a non-ISA global interrupt, 657 * then override the vector we use to setup and allocate 658 * the interrupt. 659 */ | 656 /* 657 * If the SCI is remapped to a non-ISA global interrupt, 658 * then override the vector we use to setup and allocate 659 * the interrupt. 660 */ |
660 if (intr->Interrupt > 15 && 661 intr->Source == AcpiGbl_FADT->SciInt) 662 acpi_OverrideInterruptLevel(intr->Interrupt); | 661 if (intr->GlobalIrq > 15 && 662 intr->SourceIrq == AcpiGbl_FADT.SciInterrupt) 663 acpi_OverrideInterruptLevel(intr->GlobalIrq); |
663 else | 664 else |
664 ioapic_remap_vector(new_ioapic, new_pin, intr->Source); 665 if (madt_find_interrupt(intr->Source, &old_ioapic, | 665 ioapic_remap_vector(new_ioapic, new_pin, 666 intr->SourceIrq); 667 if (madt_find_interrupt(intr->SourceIrq, &old_ioapic, |
666 &old_pin) != 0) | 668 &old_pin) != 0) |
667 printf("MADT: Could not find APIC for source IRQ %d\n", 668 intr->Source); | 669 printf("MADT: Could not find APIC for source IRQ %u\n", 670 intr->SourceIrq); |
669 else if (ioapic_get_vector(old_ioapic, old_pin) == | 671 else if (ioapic_get_vector(old_ioapic, old_pin) == |
670 intr->Source) | 672 intr->SourceIrq) |
671 ioapic_disable_pin(old_ioapic, old_pin); 672 } 673 674 /* Program the polarity and trigger mode. */ 675 ioapic_set_triggermode(new_ioapic, new_pin, trig); 676 ioapic_set_polarity(new_ioapic, new_pin, pol); 677} 678 679/* 680 * Parse an entry for an NMI routed to an IO APIC. 681 */ 682static void | 673 ioapic_disable_pin(old_ioapic, old_pin); 674 } 675 676 /* Program the polarity and trigger mode. */ 677 ioapic_set_triggermode(new_ioapic, new_pin, trig); 678 ioapic_set_polarity(new_ioapic, new_pin, pol); 679} 680 681/* 682 * Parse an entry for an NMI routed to an IO APIC. 683 */ 684static void |
683madt_parse_nmi(MADT_NMI_SOURCE *nmi) | 685madt_parse_nmi(ACPI_MADT_NMI_SOURCE *nmi) |
684{ 685 void *ioapic; 686 u_int pin; 687 | 686{ 687 void *ioapic; 688 u_int pin; 689 |
688 if (madt_find_interrupt(nmi->Interrupt, &ioapic, &pin) != 0) { 689 printf("MADT: Could not find APIC for vector %d\n", 690 nmi->Interrupt); | 690 if (madt_find_interrupt(nmi->GlobalIrq, &ioapic, &pin) != 0) { 691 printf("MADT: Could not find APIC for vector %u\n", 692 nmi->GlobalIrq); |
691 return; 692 } 693 694 ioapic_set_nmi(ioapic, pin); | 693 return; 694 } 695 696 ioapic_set_nmi(ioapic, pin); |
695 if (nmi->TriggerMode != TRIGGER_CONFORMS) | 697 if (!(nmi->IntiFlags & ACPI_MADT_TRIGGER_CONFORMS)) |
696 ioapic_set_triggermode(ioapic, pin, | 698 ioapic_set_triggermode(ioapic, pin, |
697 interrupt_trigger(nmi->TriggerMode, 0)); 698 if (nmi->Polarity != TRIGGER_CONFORMS) | 699 interrupt_trigger(nmi->IntiFlags, 0)); 700 if (!(nmi->IntiFlags & ACPI_MADT_TRIGGER_CONFORMS)) |
699 ioapic_set_polarity(ioapic, pin, | 701 ioapic_set_polarity(ioapic, pin, |
700 interrupt_polarity(nmi->Polarity, 0)); | 702 interrupt_polarity(nmi->IntiFlags, 0)); |
701} 702 703/* 704 * Parse an entry for an NMI routed to a local APIC LVT pin. 705 */ 706static void | 703} 704 705/* 706 * Parse an entry for an NMI routed to a local APIC LVT pin. 707 */ 708static void |
707madt_parse_local_nmi(MADT_LOCAL_APIC_NMI *nmi) | 709madt_parse_local_nmi(ACPI_MADT_LOCAL_APIC_NMI *nmi) |
708{ 709 u_int apic_id, pin; 710 711 if (nmi->ProcessorId == 0xff) 712 apic_id = APIC_ID_ALL; 713 else if (madt_find_cpu(nmi->ProcessorId, &apic_id) != 0) { 714 if (bootverbose) | 710{ 711 u_int apic_id, pin; 712 713 if (nmi->ProcessorId == 0xff) 714 apic_id = APIC_ID_ALL; 715 else if (madt_find_cpu(nmi->ProcessorId, &apic_id) != 0) { 716 if (bootverbose) |
715 printf("MADT: Ignoring local NMI routed to ACPI CPU %u\n", 716 nmi->ProcessorId); | 717 printf("MADT: Ignoring local NMI routed to " 718 "ACPI CPU %u\n", nmi->ProcessorId); |
717 return; 718 } 719 if (nmi->Lint == 0) 720 pin = LVT_LINT0; 721 else 722 pin = LVT_LINT1; 723 lapic_set_lvt_mode(apic_id, pin, APIC_LVT_DM_NMI); | 719 return; 720 } 721 if (nmi->Lint == 0) 722 pin = LVT_LINT0; 723 else 724 pin = LVT_LINT1; 725 lapic_set_lvt_mode(apic_id, pin, APIC_LVT_DM_NMI); |
724 if (nmi->TriggerMode != TRIGGER_CONFORMS) | 726 if (!(nmi->IntiFlags & ACPI_MADT_TRIGGER_CONFORMS)) |
725 lapic_set_lvt_triggermode(apic_id, pin, | 727 lapic_set_lvt_triggermode(apic_id, pin, |
726 interrupt_trigger(nmi->TriggerMode, 0)); 727 if (nmi->Polarity != POLARITY_CONFORMS) | 728 interrupt_trigger(nmi->IntiFlags, 0)); 729 if (!(nmi->IntiFlags & ACPI_MADT_POLARITY_CONFORMS)) |
728 lapic_set_lvt_polarity(apic_id, pin, | 730 lapic_set_lvt_polarity(apic_id, pin, |
729 interrupt_polarity(nmi->Polarity, 0)); | 731 interrupt_polarity(nmi->IntiFlags, 0)); |
730} 731 732/* 733 * Parse interrupt entries. 734 */ 735static void | 732} 733 734/* 735 * Parse interrupt entries. 736 */ 737static void |
736madt_parse_ints(APIC_HEADER *entry, void *arg __unused) | 738madt_parse_ints(ACPI_SUBTABLE_HEADER *entry, void *arg __unused) |
737{ 738 739 switch (entry->Type) { | 739{ 740 741 switch (entry->Type) { |
740 case APIC_XRUPT_OVERRIDE: | 742 case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE: |
741 madt_parse_interrupt_override( | 743 madt_parse_interrupt_override( |
742 (MADT_INTERRUPT_OVERRIDE *)entry); | 744 (ACPI_MADT_INTERRUPT_OVERRIDE *)entry); |
743 break; | 745 break; |
744 case APIC_NMI: 745 madt_parse_nmi((MADT_NMI_SOURCE *)entry); | 746 case ACPI_MADT_TYPE_NMI_SOURCE: 747 madt_parse_nmi((ACPI_MADT_NMI_SOURCE *)entry); |
746 break; | 748 break; |
747 case APIC_LOCAL_NMI: 748 madt_parse_local_nmi((MADT_LOCAL_APIC_NMI *)entry); | 749 case ACPI_MADT_TYPE_LOCAL_APIC_NMI: 750 madt_parse_local_nmi((ACPI_MADT_LOCAL_APIC_NMI *)entry); |
749 break; 750 } 751} 752 753/* 754 * Setup per-CPU ACPI IDs. 755 */ 756static void --- 4 unchanged lines hidden (view full) --- 761 u_int i; 762 763 if (madt == NULL) 764 return; 765 for (i = 0; i <= mp_maxid; i++) { 766 if (CPU_ABSENT(i)) 767 continue; 768 pc = pcpu_find(i); | 751 break; 752 } 753} 754 755/* 756 * Setup per-CPU ACPI IDs. 757 */ 758static void --- 4 unchanged lines hidden (view full) --- 763 u_int i; 764 765 if (madt == NULL) 766 return; 767 for (i = 0; i <= mp_maxid; i++) { 768 if (CPU_ABSENT(i)) 769 continue; 770 pc = pcpu_find(i); |
769 KASSERT(pc != NULL, ("no pcpu data for CPU %d", i)); | 771 KASSERT(pc != NULL, ("no pcpu data for CPU %u", i)); |
770 la = &lapics[pc->pc_apic_id]; 771 if (!la->la_enabled) 772 panic("APIC: CPU with APIC ID %u is not enabled", 773 pc->pc_apic_id); 774 pc->pc_acpi_id = la->la_acpi_id; 775 if (bootverbose) 776 printf("APIC: CPU %u has ACPI ID %u\n", i, 777 la->la_acpi_id); 778 } 779} 780SYSINIT(madt_set_ids, SI_SUB_CPU, SI_ORDER_ANY, madt_set_ids, NULL) | 772 la = &lapics[pc->pc_apic_id]; 773 if (!la->la_enabled) 774 panic("APIC: CPU with APIC ID %u is not enabled", 775 pc->pc_apic_id); 776 pc->pc_acpi_id = la->la_acpi_id; 777 if (bootverbose) 778 printf("APIC: CPU %u has ACPI ID %u\n", i, 779 la->la_acpi_id); 780 } 781} 782SYSINIT(madt_set_ids, SI_SUB_CPU, SI_ORDER_ANY, madt_set_ids, NULL) |