2 Copyright � 1995-2018, The AROS Development Team. All rights reserved.
5 http://download.intel.com/design/chipsets/datashts/29056601.pdf
8 #include <aros/macros.h>
9 #include <aros/asmcall.h>
10 #include <proto/exec.h>
11 #include <proto/arossupport.h>
12 #include <proto/acpica.h>
14 #define __KERNEL_NOLIBBASE__
15 #include <proto/kernel.h>
20 #include "kernel_base.h"
21 #include "kernel_debug.h"
22 #include "kernel_intern.h"
23 #include "kernel_globals.h"
27 #include "apic_ia32.h"
34 #define ACPI_MODPRIO_IOAPIC 50
36 /************************************************************************************************
37 ACPI IO-APIC RELATED FUNCTIONS
38 ************************************************************************************************/
40 const char *ACPI_TABLE_MADT_STR
__attribute__((weak
)) = "APIC";
45 /* descriptor for an ioapic routing table entry */
46 struct acpi_ioapic_route
48 uint32_t vect
:8, dm
:3, dstm
:1, ds
:1, pol
:1, rirr
:1, trig
:1, mask
:1, rsvd1
:15;
49 uint32_t rsvd2
:24, dst
:8;
52 static ULONG
acpi_IOAPIC_ReadReg(APTR apic_base
, UBYTE offset
)
54 *(ULONG
volatile *)(apic_base
+ IOREGSEL
) = offset
;
55 return *(ULONG
volatile *)(apic_base
+ IOREGWIN
);
58 static void acpi_IOAPIC_WriteReg(APTR apic_base
, UBYTE offset
, ULONG val
)
60 *(ULONG
volatile *)(apic_base
+ IOREGSEL
) = offset
;
61 *(ULONG
volatile *)(apic_base
+ IOREGWIN
) = val
;
64 /* IO-APIC Interrupt Functions ... ***************************/
66 struct IOAPICInt_Private
71 void ioapic_ParseTableEntry(UQUAD
*tblData
)
73 struct acpi_ioapic_route
*tblEntry
= (struct acpi_ioapic_route
*)tblData
;
75 bug("%08X%08X", ((*tblData
>> 32) & 0xFFFFFFFF), (*tblData
& 0xFFFFFFFF));
105 bug(" Logical %03u:%03u", ((tblEntry
->dst
>> 4) & 0xF), (tblEntry
->dst
& 0xF));
109 bug(" Physical %03u", (tblEntry
->dst
& 0xF));
114 icid_t
IOAPICInt_Register(struct KernelBase
*KernelBase
)
117 ACPI_OBJECT arg
= { ACPI_TYPE_INTEGER
};
118 ACPI_OBJECT_LIST arg_list
= { 1, &arg
};
120 DINT(bug("[Kernel:IOAPIC] %s()\n", __func__
));
122 /* if we have been disabled, fail to register */
123 if (IOAPICInt_IntrController
.ic_Flags
& ICF_DISABLED
)
127 * Inform ACPI/BIOS that we want to use IOAPIC mode...
128 * APIC IRQ model 0 = PIC (default)
129 * APIC IRQ model 1 = IOAPIC
130 * APIC IRQ model 2 = SIOAPIC
132 arg
.Integer
.Value
= 1;
133 status
= AcpiEvaluateObject(NULL
,
138 if (ACPI_FAILURE(status
))
140 bug("[Kernel:IOAPIC] %s: Error evaluating _PIC: %s\n", __func__
, AcpiFormatException(status
));
144 DINT(bug("[Kernel:IOAPIC] %s: IOAPIC Mode Enabled (status=%08X)\n", __func__
, status
));
146 return (icid_t
)IOAPICInt_IntrController
.ic_Node
.ln_Type
;
149 BOOL
IOAPICInt_Init(struct KernelBase
*KernelBase
, icid_t instanceCount
)
151 struct PlatformData
*kernPlatD
= (struct PlatformData
*)KernelBase
->kb_PlatformData
;
152 struct IOAPICCfgData
*ioapicData
;
153 struct IOAPICData
*ioapicPrivate
= kernPlatD
->kb_IOAPIC
;
154 struct APICData
*apicPrivate
= kernPlatD
->kb_APIC
;
155 int instance
, irq
= 0, ioapic_irqbase
;
156 struct IntrController
*xtpicIC
;
158 DINT(bug("[Kernel:IOAPIC] %s(%u)\n", __func__
, instanceCount
));
160 IOAPICInt_IntrController
.ic_Private
= ioapicPrivate
;
164 ((instance
< instanceCount
) && (ioapicData
= &ioapicPrivate
->ioapics
[instance
]));
170 ioapic_irqbase
= ioapicData
->ioapic_GSI
;
173 bug("[Kernel:IOAPIC] %s: Init IOAPIC #%u [ID=%03u] @ 0x%p\n", __func__
, instance
+ 1, ioapicData
->ioapic_ID
, ioapicData
->ioapic_Base
);
177 * Skip controllers that report bogus version information
179 ioapicval
= acpi_IOAPIC_ReadReg(
180 ioapicData
->ioapic_Base
,
182 if (ioapicval
== 0xFFFFFFFF)
186 bug("[Kernel:IOAPIC] %s: IOAPIC Version appears to be valid...\n", __func__
);
189 * Make sure we are using the correct LocalID
191 ioapicval
= acpi_IOAPIC_ReadReg(
192 ioapicData
->ioapic_Base
,
194 if (ioapicData
->ioapic_ID
!= ((ioapicval
>> 24) & 0xF))
196 ioapicval
&= ~(0xF << 24);
197 ioapicval
|= (ioapicData
->ioapic_ID
<< 24);
199 acpi_IOAPIC_WriteReg(ioapicData
->ioapic_Base
,
202 DINT(bug("[Kernel:IOAPIC] %s: IOAPIC LocalID configured\n", __func__
);)
205 /* Check if the 8259A has been registered, and disable it */
206 if ((instance
== 0) && ((xtpicIC
= krnFindInterruptController(KernelBase
, ICTYPE_I8259A
)) != NULL
))
208 DINT(bug("[Kernel:IOAPIC] %s: Disabling i8259A controller...\n", __func__
);)
212 DINT(bug("[Kernel:IOAPIC] %s: Configuring IRQs & routing\n", __func__
);)
214 if ((ioapicData
->ioapic_RouteTable
= AllocMem(ioapicData
->ioapic_IRQCount
* sizeof(UQUAD
), MEMF_ANY
)) != NULL
)
216 DINT(bug("[Kernel:IOAPIC] %s: Routing Data @ 0x%p\n", __func__
, ioapicData
->ioapic_RouteTable
));
217 for (irq
= ioapic_irqbase
; irq
< (ioapic_irqbase
+ ioapicData
->ioapic_IRQCount
); irq
++)
219 UBYTE ioapic_pin
= irq
- ioapic_irqbase
;
220 struct acpi_ioapic_route
*irqRoute
= (struct acpi_ioapic_route
*)&ioapicData
->ioapic_RouteTable
[ioapic_pin
];
221 struct IntrMapping
*intrMap
= krnInterruptMapped(KernelBase
, irq
);
222 BOOL enabled
= FALSE
;
225 DINT(bug("[Kernel:IOAPIC] %s: Route Entry %u @ 0x%p\n", __func__
, ioapic_pin
, irqRoute
));
227 ioapicval
= acpi_IOAPIC_ReadReg(
228 ioapicData
->ioapic_Base
,
229 IOAPICREG_REDTBLBASE
+ (ioapic_pin
<< 1));
230 ioapicData
->ioapic_RouteTable
[ioapic_pin
] = (UQUAD
)ioapicval
;
232 ioapicval
= acpi_IOAPIC_ReadReg(
233 ioapicData
->ioapic_Base
,
234 IOAPICREG_REDTBLBASE
+ (ioapic_pin
<< 1) + 1);
235 ioapicData
->ioapic_RouteTable
[ioapic_pin
] |= ((UQUAD
)ioapicval
<< 32);
239 if (ioapic_pin
< I8259A_IRQCOUNT
)
241 /* mark the ISA interrupts as active high, edge triggered... */
247 /* ...and PCI interrupts as active low, level triggered */
252 /* setup delivery to the boot processor */
255 irqRoute
->vect
= (UBYTE
)intrMap
->im_Node
.ln_Pri
+ HW_IRQ_BASE
;
256 if (ictl_is_irq_enabled(intrMap
->im_Node
.ln_Pri
, KernelBase
))
260 irqRoute
->vect
= irq
+ HW_IRQ_BASE
;
261 D(bug("[Kernel:IOAPIC] %s: Routing HW IRQ to Vector #$%02X\n", __func__
, irqRoute
->vect
);)
262 irqRoute
->dm
= 0; // fixed
263 irqRoute
->dstm
= 0; // physical
266 irqRoute
->dst
= apicPrivate
->cores
[0].cpu_LocalID
;
270 if ((KrnIsSuper()) || ((ssp
= SuperState()) != NULL
))
272 if (!krnInitInterrupt(KernelBase
, irq
, IOAPICInt_IntrController
.ic_Node
.ln_Type
, instance
))
274 bug("[Kernel:IOAPIC] %s: Failed to acquire IRQ #$%02X\n", __func__
, irq
);
278 if (!core_SetIRQGate(apicPrivate
->cores
[0].cpu_IDT
, irq
, (uintptr_t)IntrDefaultGates
[HW_IRQ_BASE
+ irq
]))
280 bug("[Kernel:IOAPIC] %s: failed to set IRQ %d's gate\n", __func__
, irq
);
282 if ((!krnInterruptMapping(KernelBase
, irq
)) && (ictl_is_irq_enabled(irq
, KernelBase
)))
288 acpi_IOAPIC_WriteReg(ioapicData
->ioapic_Base
,
289 IOAPICREG_REDTBLBASE
+ (ioapic_pin
<< 1 ) + 1,
290 ((ioapicData
->ioapic_RouteTable
[ioapic_pin
] >> 32) & 0xFFFFFFFF));
291 acpi_IOAPIC_WriteReg(ioapicData
->ioapic_Base
,
292 IOAPICREG_REDTBLBASE
+ (ioapic_pin
<< 1),
293 (ioapicData
->ioapic_RouteTable
[ioapic_pin
] & 0xFFFFFFFF));
297 acpi_IOAPIC_WriteReg(ioapicData
->ioapic_Base
,
298 IOAPICREG_REDTBLBASE
+ (ioapic_pin
<< 1),
299 (ioapicData
->ioapic_RouteTable
[ioapic_pin
] & 0xFFFFFFFF));
302 bug("[Kernel:IOAPIC] %s: ", __func__
);
303 ioapic_ParseTableEntry((UQUAD
*)&ioapicData
->ioapic_RouteTable
[ioapic_pin
]);
308 ioapic_irqbase
+= ioapicData
->ioapic_IRQCount
;
314 BOOL
IOAPICInt_DisableIRQ(APTR icPrivate
, icid_t icInstance
, icid_t intNum
)
316 struct IOAPICData
*ioapicPrivate
= (struct IOAPICData
*)icPrivate
;
317 struct IOAPICCfgData
*ioapicData
= &ioapicPrivate
->ioapics
[icInstance
];
318 struct IntrMapping
*intrMap
= krnInterruptMapping(KernelBase
, intNum
);
319 struct acpi_ioapic_route
*irqRoute
;
322 DINT(bug("[Kernel:IOAPIC] %s(%02X)\n", __func__
, intNum
));
326 ioapic_pin
= (intrMap
->im_IRQ
- ioapicData
->ioapic_GSI
);
329 ioapic_pin
= intNum
- ioapicData
->ioapic_GSI
;
331 DINT(bug("[Kernel:IOAPIC] %s: IOAPIC Pin %02X\n", __func__
, ioapic_pin
));
332 irqRoute
= (struct acpi_ioapic_route
*)&ioapicData
->ioapic_RouteTable
[ioapic_pin
];
336 acpi_IOAPIC_WriteReg(ioapicData
->ioapic_Base
,
337 IOAPICREG_REDTBLBASE
+ (ioapic_pin
<< 1),
338 (ioapicData
->ioapic_RouteTable
[ioapic_pin
] & 0xFFFFFFFF));
339 acpi_IOAPIC_WriteReg(ioapicData
->ioapic_Base
,
340 IOAPICREG_REDTBLBASE
+ (ioapic_pin
<< 1 ) + 1,
341 ((ioapicData
->ioapic_RouteTable
[ioapic_pin
] >> 32) & 0xFFFFFFFF));
346 BOOL
IOAPICInt_EnableIRQ(APTR icPrivate
, icid_t icInstance
, icid_t intNum
)
348 struct PlatformData
*kernPlatD
= (struct PlatformData
*)KernelBase
->kb_PlatformData
;
349 struct IOAPICData
*ioapicPrivate
= (struct IOAPICData
*)icPrivate
;
350 struct IOAPICCfgData
*ioapicData
= &ioapicPrivate
->ioapics
[icInstance
];
351 struct IntrMapping
*intrMap
= krnInterruptMapping(KernelBase
, intNum
);
352 struct APICData
*apicPrivate
= kernPlatD
->kb_APIC
;
353 struct acpi_ioapic_route
*irqRoute
;
356 DINT(bug("[Kernel:IOAPIC] %s(%02X)\n", __func__
, intNum
));
360 ioapic_pin
= (intrMap
->im_IRQ
- ioapicData
->ioapic_GSI
);
363 ioapic_pin
= intNum
- ioapicData
->ioapic_GSI
;
365 DINT(bug("[Kernel:IOAPIC] %s: IOAPIC Pin %02X\n", __func__
, ioapic_pin
));
366 irqRoute
= (struct acpi_ioapic_route
*)&ioapicData
->ioapic_RouteTable
[ioapic_pin
];
369 * if we have APIC's get the ID from there
370 * otherwise use the pre-configured one. */
373 apicid_t cpuNo
= KrnGetCPUNumber();
374 irqRoute
->dst
= apicPrivate
->cores
[cpuNo
].cpu_LocalID
;
377 irqRoute
->vect
= intNum
+ HW_IRQ_BASE
;
378 irqRoute
->mask
= 0; // enable!!
380 acpi_IOAPIC_WriteReg(ioapicData
->ioapic_Base
,
381 IOAPICREG_REDTBLBASE
+ (ioapic_pin
<< 1 ) + 1,
382 ((ioapicData
->ioapic_RouteTable
[ioapic_pin
] >> 32) & 0xFFFFFFFF));
383 acpi_IOAPIC_WriteReg(ioapicData
->ioapic_Base
,
384 IOAPICREG_REDTBLBASE
+ (ioapic_pin
<< 1),
385 (ioapicData
->ioapic_RouteTable
[ioapic_pin
] & 0xFFFFFFFF));
390 BOOL
IOAPICInt_AckIntr(APTR icPrivate
, icid_t icInstance
, icid_t intNum
)
394 DINT(bug("[Kernel:IOAPIC] %s()\n", __func__
));
396 /* Write zero to EOI of APIC */
397 apic_base
= core_APIC_GetBase();
399 APIC_REG(apic_base
, APIC_EOI
) = 0;
404 struct IntrController IOAPICInt_IntrController
=
407 .ln_Name
= "82093AA IO-APIC",
411 AROS_MAKE_ID('I','O','9','3'),
417 IOAPICInt_DisableIRQ
,
421 /********************************************************************/
423 void acpi_IOAPIC_AllocPrivate(struct PlatformData
*pdata
)
425 if (!pdata
->kb_IOAPIC
)
427 pdata
->kb_IOAPIC
= AllocMem(sizeof(struct IOAPICData
) + pdata
->kb_ACPI
->acpi_ioapicCnt
* sizeof(struct IOAPICCfgData
), MEMF_CLEAR
);
428 D(bug("[Kernel:ACPI-IOAPIC] IO-APIC Private @ 0x%p, for %u IOAPIC's\n", pdata
->kb_IOAPIC
, pdata
->kb_ACPI
->acpi_ioapicCnt
));
432 /* Process the 'Interrupt Source' MADT Table */
433 AROS_UFH2(IPTR
, ACPI_hook_Table_Int_Src_Parse
,
434 AROS_UFHA(struct Hook
*, table_hook
, A0
),
435 AROS_UFHA(ACPI_MADT_INTERRUPT_SOURCE
*, intsrc
, A2
))
439 DPARSE(bug("[Kernel:ACPI-IOAPIC] ## %s()\n", __func__
));
440 DPARSE(bug("[Kernel:ACPI-IOAPIC] %s: %u:%u, GSI %u, Flags 0x%x\n", __func__
, intsrc
->Id
, intsrc
->Eid
,
441 intsrc
->GlobalIrq
, intsrc
->IntiFlags
));
443 if (intsrc
->Type
== 1)
445 bug("[Kernel:ACPI-IOAPIC] %s: PMI, vector %d\n", __func__
, intsrc
->IoSapicVector
);
447 else if(intsrc
->Type
== 2)
449 bug("[Kernel:ACPI-IOAPIC] %s: INIT\n", __func__
);
451 else if(intsrc
->Type
== 3)
453 bug("[Kernel:ACPI-IOAPIC] %s: Corrected\n", __func__
);
461 /* Process the 'Interrupt Source Overide' MADT Table */
462 AROS_UFH2(IPTR
, ACPI_hook_Table_Int_Src_Ovr_Parse
,
463 AROS_UFHA(struct Hook
*, table_hook
, A0
),
464 AROS_UFHA(ACPI_MADT_INTERRUPT_OVERRIDE
*, intsrc
, A2
))
468 struct IntrMapping
*intrMap
;
470 DPARSE(bug("[Kernel:ACPI-IOAPIC] ## %s()\n", __func__
));
471 DPARSE(bug("[Kernel:ACPI-IOAPIC] %s: Bus %u, Source IRQ %u, GSI %u, Flags 0x%x\n", __func__
, intsrc
->Bus
, intsrc
->SourceIrq
,
472 intsrc
->GlobalIrq
, intsrc
->IntiFlags
));
474 intrMap
= AllocMem(sizeof(struct IntrMapping
), MEMF_CLEAR
);
475 intrMap
->im_Node
.ln_Pri
= intsrc
->SourceIrq
;
476 //intrMap->im_Node.ln_Type = IOAPICInt_IntrController->;
477 intrMap
->im_IRQ
= intsrc
->GlobalIrq
;
478 Enqueue(&KernelBase
->kb_InterruptMappings
, &intrMap
->im_Node
);
485 /* Process the 'Non-Maskable Interrupt Source' MADT Table */
486 AROS_UFH2(IPTR
, ACPI_hook_Table_NMI_Src_Parse
,
487 AROS_UFHA(struct Hook
*, table_hook
, A0
),
488 AROS_UFHA(ACPI_MADT_NMI_SOURCE
*, nmi_src
, A2
))
492 DPARSE(bug("[Kernel:ACPI-IOAPIC] ## %s()\n", __func__
));
493 DPARSE(bug("[Kernel:ACPI-IOAPIC] %s: GSI %u, Flags 0x%x\n", __func__
, nmi_src
->GlobalIrq
, nmi_src
->IntiFlags
));
495 /* FIXME: Uh... shouldn't we do something with this? */
502 /* Process the 'IO-APIC' MADT Table */
503 AROS_UFH3(IPTR
, ACPI_hook_Table_IOAPIC_Parse
,
504 AROS_UFHA(struct Hook
*, table_hook
, A0
),
505 AROS_UFHA(ACPI_MADT_IO_APIC
*, ioapic
, A2
),
506 AROS_UFHA(struct ACPI_TABLESCAN_DATA
*, tsdata
, A1
))
510 struct PlatformData
*pdata
= tsdata
->acpits_UserData
;
512 DPARSE(bug("[Kernel:ACPI-IOAPIC] ## %s()\n", __func__
));
514 if (!pdata
->kb_IOAPIC
)
516 acpi_IOAPIC_AllocPrivate(pdata
);
519 if (pdata
->kb_IOAPIC
)
521 icintrid_t ioapicICInstID
;
525 bug("[Kernel:ACPI-IOAPIC] Registering IO-APIC #%u [ID=%03u] @ %p [GSI = %u]\n",
526 pdata
->kb_IOAPIC
->ioapic_count
+ 1, ioapic
->Id
, ioapic
->Address
, ioapic
->GlobalIrqBase
);
528 if ((ioapicICInstID
= krnAddInterruptController(KernelBase
, &IOAPICInt_IntrController
)) != (icintrid_t
)-1)
530 struct IOAPICCfgData
*ioapicData
= (struct IOAPICCfgData
*)&pdata
->kb_IOAPIC
->ioapics
[pdata
->kb_IOAPIC
->ioapic_count
];
532 DPARSE(bug("[Kernel:ACPI-IOAPIC] IO-APIC IC ID #%u:%u\n", ICINTR_ICID(ioapicICInstID
), ICINTR_INST(ioapicICInstID
)));
534 ioapicData
->ioapic_Base
= (APTR
)((IPTR
)ioapic
->Address
);
535 ioapicData
->ioapic_GSI
= ioapic
->GlobalIrqBase
;
537 ioapicval
= acpi_IOAPIC_ReadReg(
538 ioapicData
->ioapic_Base
,
540 ioapicData
->ioapic_ID
= ioapic
->Id
; // we store the ACPI reported ID here, so we can check it during init.
542 DPARSE(bug("[Kernel:ACPI-IOAPIC] %s: #%u,",
543 __func__
, ((ioapicval
>> 24) & 0xF)));
545 ioapicval
= acpi_IOAPIC_ReadReg(
546 ioapicData
->ioapic_Base
,
548 ioapicData
->ioapic_IRQCount
= ((ioapicval
>> 16) & 0xFF) + 1;
549 ioapicData
->ioapic_Ver
= (ioapicval
& 0xFF);
550 DPARSE(bug(" ver %u, max irqs = %u,",
551 ioapicData
->ioapic_Ver
, ioapicData
->ioapic_IRQCount
));
552 ioapicval
= acpi_IOAPIC_ReadReg(
553 ioapicData
->ioapic_Base
,
555 DPARSE(bug("arb %d\n", ((ioapicval
>> 24) & 0xF)));
557 for (i
= 0; i
< (ioapicData
->ioapic_IRQCount
<< 1); i
+= 2)
561 ioapicval
= acpi_IOAPIC_ReadReg(
562 ioapicData
->ioapic_Base
,
563 IOAPICREG_REDTBLBASE
+ i
);
564 tblraw
= ((UQUAD
)ioapicval
<< 32);
566 ioapicval
= acpi_IOAPIC_ReadReg(
567 ioapicData
->ioapic_Base
,
568 IOAPICREG_REDTBLBASE
+ i
+ 1);
569 tblraw
|= (UQUAD
)ioapicval
;
572 bug("[Kernel:ACPI-IOAPIC] %s: ", __func__
);
573 ioapic_ParseTableEntry(&tblraw
);
578 pdata
->kb_IOAPIC
->ioapic_count
++;
587 * Process the 'IO-APIC' MADT Table
588 * This function counts the available IO-APICs.
590 AROS_UFH3(static IPTR
, ACPI_hook_Table_IOAPIC_Count
,
591 AROS_UFHA(struct Hook
*, table_hook
, A0
),
592 AROS_UFHA(ACPI_MADT_IO_APIC
*, ioapic
, A2
),
593 AROS_UFHA(struct ACPI_TABLESCAN_DATA
*, tsdata
, A1
))
597 struct PlatformData
*pdata
= tsdata
->acpits_UserData
;
598 struct ACPI_TABLE_HOOK
*scanHook
;
600 DPARSE(bug("[Kernel:ACPI-IOAPIC] ## %s()\n", __func__
));
602 if (pdata
->kb_ACPI
->acpi_ioapicCnt
== 0)
604 DPARSE(bug("[Kernel:ACPI-IOAPIC] %s: Registering IO-APIC Table Parser...\n", __func__
));
606 scanHook
= (struct ACPI_TABLE_HOOK
*)AllocMem(sizeof(struct ACPI_TABLE_HOOK
), MEMF_CLEAR
);
609 scanHook
->acpith_Node
.ln_Name
= (char *)ACPI_TABLE_MADT_STR
;
610 scanHook
->acpith_Node
.ln_Pri
= ACPI_MODPRIO_IOAPIC
- 10; /* Queue 10 priority levels after the module parser */
611 scanHook
->acpith_Hook
.h_Entry
= (APTR
)ACPI_hook_Table_IOAPIC_Parse
;
612 scanHook
->acpith_HeaderLen
= sizeof(ACPI_TABLE_MADT
);
613 scanHook
->acpith_EntryType
= ACPI_MADT_TYPE_IO_APIC
;
614 scanHook
->acpith_UserData
= pdata
;
615 Enqueue(&pdata
->kb_ACPI
->acpi_tablehooks
, &scanHook
->acpith_Node
);
618 scanHook
= (struct ACPI_TABLE_HOOK
*)AllocMem(sizeof(struct ACPI_TABLE_HOOK
), MEMF_CLEAR
);
621 DPARSE(bug("[Kernel:ACPI-IOAPIC] %s: Registering Interrupt Source Table Parser...\n", __func__
));
623 scanHook
->acpith_Node
.ln_Name
= (char *)ACPI_TABLE_MADT_STR
;
624 scanHook
->acpith_Node
.ln_Pri
= ACPI_MODPRIO_IOAPIC
- 20; /* Queue 20 priority levels after the module parser */
625 scanHook
->acpith_Hook
.h_Entry
= (APTR
)ACPI_hook_Table_Int_Src_Parse
;
626 scanHook
->acpith_HeaderLen
= sizeof(ACPI_TABLE_MADT
);
627 scanHook
->acpith_EntryType
= ACPI_MADT_TYPE_INTERRUPT_SOURCE
;
628 scanHook
->acpith_UserData
= pdata
;
629 Enqueue(&pdata
->kb_ACPI
->acpi_tablehooks
, &scanHook
->acpith_Node
);
632 scanHook
= (struct ACPI_TABLE_HOOK
*)AllocMem(sizeof(struct ACPI_TABLE_HOOK
), MEMF_CLEAR
);
635 DPARSE(bug("[Kernel:ACPI-IOAPIC] %s: Registering Interrupt Override Table Parser...\n", __func__
));
637 scanHook
->acpith_Node
.ln_Name
= (char *)ACPI_TABLE_MADT_STR
;
638 scanHook
->acpith_Node
.ln_Pri
= ACPI_MODPRIO_IOAPIC
- 30; /* Queue 30 priority levels after the module parser */
639 scanHook
->acpith_Hook
.h_Entry
= (APTR
)ACPI_hook_Table_Int_Src_Ovr_Parse
;
640 scanHook
->acpith_HeaderLen
= sizeof(ACPI_TABLE_MADT
);
641 scanHook
->acpith_EntryType
= ACPI_MADT_TYPE_INTERRUPT_OVERRIDE
;
642 scanHook
->acpith_UserData
= pdata
;
643 Enqueue(&pdata
->kb_ACPI
->acpi_tablehooks
, &scanHook
->acpith_Node
);
646 scanHook
= (struct ACPI_TABLE_HOOK
*)AllocMem(sizeof(struct ACPI_TABLE_HOOK
), MEMF_CLEAR
);
649 DPARSE(bug("[Kernel:ACPI-IOAPIC] %s: Registering NMI Source Table Parser...\n", __func__
));
651 scanHook
->acpith_Node
.ln_Name
= (char *)ACPI_TABLE_MADT_STR
;
652 scanHook
->acpith_Node
.ln_Pri
= ACPI_MODPRIO_IOAPIC
- 40; /* Queue 40 priority levels after the module parser */
653 scanHook
->acpith_Hook
.h_Entry
= (APTR
)ACPI_hook_Table_NMI_Src_Parse
;
654 scanHook
->acpith_HeaderLen
= sizeof(ACPI_TABLE_MADT
);
655 scanHook
->acpith_EntryType
= ACPI_MADT_TYPE_NMI_SOURCE
;
656 scanHook
->acpith_UserData
= pdata
;
657 Enqueue(&pdata
->kb_ACPI
->acpi_tablehooks
, &scanHook
->acpith_Node
);
660 pdata
->kb_ACPI
->acpi_ioapicCnt
++;
668 void ACPI_IOAPIC_SUPPORT(struct PlatformData
*pdata
)
670 struct ACPI_TABLE_HOOK
*scanHook
;
671 struct TagItem
*cmdTags
= LibFindTagItem(KRN_CmdLine
, BootMsg
);
673 if (cmdTags
&& strstr((const char *)cmdTags
->ti_Data
, "noioapic"))
675 D(bug("[Kernel:ACPI-IOAPIC] %s: IOAPIC Support Disabled\n", __func__
));
679 scanHook
= (struct ACPI_TABLE_HOOK
*)AllocMem(sizeof(struct ACPI_TABLE_HOOK
), MEMF_CLEAR
);
682 D(bug("[Kernel:ACPI-IOAPIC] %s: Registering IOAPIC Table Parser...\n", __func__
));
683 D(bug("[Kernel:ACPI-IOAPIC] %s: Table Hook @ 0x%p\n", __func__
, scanHook
));
684 scanHook
->acpith_Node
.ln_Name
= (char *)ACPI_TABLE_MADT_STR
;
685 scanHook
->acpith_Node
.ln_Pri
= ACPI_MODPRIO_IOAPIC
;
686 scanHook
->acpith_Hook
.h_Entry
= (APTR
)ACPI_hook_Table_IOAPIC_Count
;
687 scanHook
->acpith_HeaderLen
= sizeof(ACPI_TABLE_MADT
);
688 scanHook
->acpith_EntryType
= ACPI_MADT_TYPE_IO_APIC
;
689 scanHook
->acpith_UserData
= pdata
;
690 Enqueue(&pdata
->kb_ACPI
->acpi_tablehooks
, &scanHook
->acpith_Node
);
692 D(bug("[Kernel:ACPI-IOAPIC] %s: Registering done\n", __func__
));
695 DECLARESET(KERNEL__ACPISUPPORT
)
696 ADD2SET(ACPI_IOAPIC_SUPPORT
, KERNEL__ACPISUPPORT
, 0)