2 Copyright � 1995-2008, The AROS Development Team. All rights reserved.
3 $Id: acpi_parsers.c,v 1.7 2004/01/07 07:13:03 nicja Exp $
7 #include "exec_intern.h"
13 #include <asm/segments.h>
14 #include <aros/libcall.h>
15 #include <aros/asmcall.h>
16 #include <exec/execbase.h>
17 #include <hardware/intbits.h>
19 #include "kernel_intern.h"
23 /************************************************************************************************
24 ACPI TABLE PARSING HOOKS
25 ************************************************************************************************/
27 extern IPTR _Kern_APICTrampolineBase
;
29 /* Process the 'Multiple APIC Description Table' Table */
30 AROS_UFH1(int, ACPI_hook_Table_MADT_Parse
,
31 AROS_UFHA(struct acpi_table_hook
*, table_hook
, A0
))
35 rkprintf("[Kernel] (HOOK) ACPI_hook_Table_MADT_Parse()\n");
37 struct acpi_table_madt
*madt
= NULL
;
39 struct KernelBase
*KernelBase
= TLS_GET(KernelBase
);
41 if (!table_hook
->phys_addr
|| !table_hook
->size
)
43 rkprintf("[Kernel] (HOOK) ACPI_hook_Table_MADT_Parse: Illegal MADT Table Addr/Size\n");
47 madt
= (struct acpi_table_madt
*) table_hook
->phys_addr
;
49 if (madt
->lapic_address
)
51 KernelBase
->kb_APICBase
= madt
->lapic_address
;
52 rkprintf("[Kernel] (HOOK) ACPI_hook_Table_MADT_Parse: Local APIC address 0x%08x\n", KernelBase
->kb_APICBase
);
59 /* Process the 'Local APIC' MADT Table */
60 AROS_UFH1(int, ACPI_hook_Table_LAPIC_Parse
,
61 AROS_UFHA(struct acpi_madt_entry_hook
*, table_hook
, A0
))
65 rkprintf("[Kernel] (HOOK) ACPI_hook_Table_LAPIC_Parse()\n");
67 struct KernelBase
*KernelBase
= TLS_GET(KernelBase
);
68 struct acpi_table_lapic
*processor
= NULL
;
70 if (!table_hook
->header
)
72 rkprintf("[Kernel] (HOOK) ACPI_hook_Table_LAPIC_Parse: Illegal LAPIC Table Addr\n");
76 processor
= (struct acpi_table_lapic
*) table_hook
->header
;
78 rkprintf("[Kernel] (HOOK) ACPI_hook_Table_LAPIC_Parse: Local APIC %d:%d [Flags=%08x]\n", processor
->acpi_id
, processor
->id
, processor
->flags
);
80 #if defined(CONFIG_LAPICS)
81 if ((KernelBase
->kb_APICIDMap
[0] != processor
->acpi_id
) && processor
->flags
.enabled
)
83 if (_Kern_APICTrampolineBase
!= NULL
)
85 rkprintf("[Kernel] (HOOK) ACPI_hook_Table_LAPIC_Parse: Registering NEW APIC\n");
88 UBYTE apic_newid
= KernelBase
->kb_APICCount
++;
89 UBYTE
*apic_oldmap
= KernelBase
->kb_APICIDMap
;
91 KernelBase
->kb_APICIDMap
= AllocVec(KernelBase
->kb_APICCount
, MEMF_CLEAR
);
92 for (apic_count
= 0; apic_count
< apic_newid
; apic_count
++)
94 KernelBase
->kb_APICIDMap
[apic_count
] == apic_oldmap
[apic_count
];
98 KernelBase
->kb_APICIDMap
[apic_newid
] != processor
->acpi_id
;
101 /* Allow access to page 0 again */
102 core_ProtKernelArea(0, 1, 1, 1, 1);
104 rkprintf("[Kernel] (HOOK) ACPI_hook_Table_LAPIC_Parse: Setting warm reset code ..\n");
111 unsigned long scratchreg
;
115 "movq %0, %%cr3":"=r"(scratchreg
)::"memory");
118 /* 40:67 set to _Kern_APICTrampolineBase so that APIC recieves it in CS:IP */
119 rkprintf("[Kernel] (HOOK) ACPI_hook_Table_LAPIC_Parse: Setting vector for trampoline @ %p ..\n", _Kern_APICTrampolineBase
);
120 *((volatile unsigned short *)0x469) = _Kern_APICTrampolineBase
>> 4;
121 *((volatile unsigned short *)0x467) = _Kern_APICTrampolineBase
& 0xf;
123 /* Start IPI sequence */
124 unsigned long wakeresult
= core_APICIPIWake(processor
->acpi_id
, _Kern_APICTrampolineBase
);
127 /* Lock page 0 access again! */
128 core_ProtKernelArea(0, 1, 0, 0, 0);
131 rkprintf("[Kernel] (HOOK) ACPI_hook_Table_LAPIC_Parse: core_APICIPIWake returns %d\n",wakeresult
);
135 rkprintf("[Kernel] (HOOK) ACPI_hook_Table_LAPIC_Parse: Warning - No APIC Trampoline.. Cannot start apic id %d\n", processor
->acpi_id
);
145 /* Process the 'Local APIC Address Overide' MADT Table */
146 AROS_UFH1(int, ACPI_hook_Table_LAPIC_Addr_Ovr_Parse
,
147 AROS_UFHA(struct acpi_madt_entry_hook
*, table_hook
, A0
))
151 rkprintf("[Kernel] (HOOK) ACPI_hook_Table_LAPIC_Addr_Ovr_Parse()\n");
153 struct acpi_table_lapic_addr_ovr
*lapic_addr_ovr
= NULL
;
155 if (!table_hook
->header
)
157 rkprintf("[Kernel] (HOOK) ACPI_hook_Table_LAPIC_Addr_Ovr_Parse: Illegal LAPIC_Addr_Ovr Table Addr\n");
161 lapic_addr_ovr
= (struct acpi_table_lapic_addr_ovr
*) table_hook
->header
;
163 rkprintf("[Kernel] (HOOK) ACPI_hook_Table_LAPIC_Addr_Ovr_Parse: Local APIC address 0x%08x\n", lapic_addr_ovr
->address
);
170 /* Process the 'Local APIC Non-Maskable Interrupt' MADT Table */
171 AROS_UFH1(int, ACPI_hook_Table_LAPIC_NMI_Parse
,
172 AROS_UFHA(struct acpi_madt_entry_hook
*, table_hook
, A0
))
176 rkprintf("[Kernel] (HOOK) ACPI_hook_Table_LAPIC_NMI_Parse()\n");
178 struct acpi_table_lapic_nmi
*lapic_nmi
= NULL
;
180 if (!table_hook
->header
)
182 rkprintf("[Kernel] (HOOK) ACPI_hook_Table_LAPIC_NMI_Parse: Illegal LAPIC_NMI Table Addr\n");
186 lapic_nmi
= (struct acpi_table_lapic_nmi
*) table_hook
->header
;
188 if (lapic_nmi
->lint
!= 1)
190 rkprintf("[Kernel] (HOOK) ACPI_hook_Table_LAPIC_NMI_Parse: WARNING - NMI not connected to LINT1!\n");
198 /* Process the 'IO-APIC' MADT Table */
199 AROS_UFH1(int, ACPI_hook_Table_IOAPIC_Parse
,
200 AROS_UFHA(struct acpi_madt_entry_hook
*, table_hook
, A0
))
204 rkprintf("[Kernel] (HOOK) ACPI_hook_Table_IOAPIC_Parse()\n");
206 struct acpi_table_ioapic
*ioapic
= NULL
;
208 if (!table_hook
->header
)
210 rkprintf("[Kernel] (HOOK) ACPI_hook_Table_IOAPIC_Parse: Illegal IOAPIC Table Addr\n");
214 ioapic
= (struct acpi_table_ioapic
*) table_hook
->header
;
216 rkprintf("[Kernel] (HOOK) ACPI_hook_Table_IOAPIC_Parse: IOAPIC %d @ %p [irq base = %d]\n", ioapic
->id
, ioapic
->address
, ioapic
->global_irq_base
);
223 /* Process the 'Interrupt Source Overide' MADT Table */
224 AROS_UFH1(int, ACPI_hook_Table_Int_Src_Ovr_Parse
,
225 AROS_UFHA(struct acpi_madt_entry_hook
*, table_hook
, A0
))
229 rkprintf("[Kernel] (HOOK) ACPI_hook_Table_Int_Src_Ovr_Parse()\n");
231 struct acpi_table_int_src_ovr
*intsrc
= NULL
;
233 if (!table_hook
->header
)
235 rkprintf("[Kernel] (HOOK) ACPI_hook_Table_Int_Src_Ovr_Parse: Illegal Int_Src_Ovr Table Addr\n");
239 intsrc
= (struct acpi_table_int_src_ovr
*) table_hook
->header
;
241 rkprintf("[Kernel] (HOOK) ACPI_hook_Table_Int_Src_Ovr_Parse: BUS IRQ %d, Global IRQ %d, polarity ##, trigger ##\n", intsrc
->bus_irq
, intsrc
->global_irq
);
242 //intsrc->flags.polarity,
243 //intsrc->flags.trigger,
250 /* Process the 'Non-Maskable Interrupt Source' MADT Table */
251 AROS_UFH1(int, ACPI_hook_Table_NMI_Src_Parse
,
252 AROS_UFHA(struct acpi_madt_entry_hook
*, table_hook
, A0
))
256 rkprintf("[Kernel] (HOOK) ACPI_hook_Table_NMI_Src_Parse()\n");
258 struct acpi_table_nmi_src
*nmi_src
= NULL
;
260 if (!table_hook
->header
)
262 rkprintf("[Kernel] (HOOK) ACPI_hook_Table_NMI_Src_Parse: Illegal NMI_Src Table Addr\n");
266 nmi_src
= (struct acpi_table_nmi_src
*) table_hook
->header
;
273 /* Process the 'High Precision Event Timer' Table */
274 AROS_UFH1(int, ACPI_hook_Table_HPET_Parse
,
275 AROS_UFHA(struct acpi_table_hook
*, table_hook
, A0
))
279 rkprintf("[Kernel] (HOOK) ACPI_hook_Table_HPET_Parse()\n");
281 struct acpi_table_hpet
*hpet_tbl
;
283 if (!table_hook
->phys_addr
|| !table_hook
->size
)
285 rkprintf("[Kernel] (HOOK) ACPI_hook_Table_HPET_Parse: Illegal HPET Table Addr/Size\n");
289 hpet_tbl
= (struct acpi_table_hpet
*) table_hook
->phys_addr
;
291 if (hpet_tbl
->addr
.space_id
!= ACPI_SPACE_MEM
)
293 rkprintf("[Kernel] (HOOK) ACPI_hook_Table_HPET_Parse: HPET timers must be located in memory.\n");
297 rkprintf("[Kernel] (HOOK) ACPI_hook_Table_HPET_Parse: INFORMATION - HPET id: %d @ %p\n", hpet_tbl
->id
, hpet_tbl
->addr
.addrl
);
304 /************************************************************************************************/