make the linux-ppc packags be in synch with other platforms
[tangerine.git] / arch / x86_64-pc / kernel / acpi_parsers.c
blob9b10afed8c74a9bdedcef75b81f7cf5b5ac2b1af
1 /*
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 $
4 */
5 #include <inttypes.h>
7 #include "exec_intern.h"
8 #include "etask.h"
10 #include <stdio.h>
11 #include <asm/cpu.h>
12 #include <asm/io.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"
21 #define CONFIG_LAPICS
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))
33 AROS_USERFUNC_INIT
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");
44 return 0;
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);
54 return 1;
56 AROS_USERFUNC_EXIT
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))
63 AROS_USERFUNC_INIT
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");
73 return 0;
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");
87 UBYTE apic_count;
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];
96 FreeVec(apic_oldmap);
98 KernelBase->kb_APICIDMap[apic_newid] != processor->acpi_id;
100 #if (0)
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");
105 outb(0xf, 0x70);
106 outb(0xa, 0x71);
108 /* Flush TLB */
111 unsigned long scratchreg;
113 asm volatile(
114 "movq %%cr3, %0\n\t"
115 "movq %0, %%cr3":"=r"(scratchreg)::"memory");
116 } while (0);
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;
122 #endif
123 /* Start IPI sequence */
124 unsigned long wakeresult = core_APICIPIWake(processor->acpi_id, _Kern_APICTrampolineBase);
126 #if (0)
127 /* Lock page 0 access again! */
128 core_ProtKernelArea(0, 1, 0, 0, 0);
129 #endif
131 rkprintf("[Kernel] (HOOK) ACPI_hook_Table_LAPIC_Parse: core_APICIPIWake returns %d\n",wakeresult);
133 else
135 rkprintf("[Kernel] (HOOK) ACPI_hook_Table_LAPIC_Parse: Warning - No APIC Trampoline.. Cannot start apic id %d\n", processor->acpi_id);
136 return 0;
139 #endif
140 return 1;
142 AROS_USERFUNC_EXIT
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))
149 AROS_USERFUNC_INIT
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");
158 return 0;
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);
165 return 1;
167 AROS_USERFUNC_EXIT
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))
174 AROS_USERFUNC_INIT
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");
183 return 0;
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");
193 return 1;
195 AROS_USERFUNC_EXIT
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))
202 AROS_USERFUNC_INIT
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");
211 return 0;
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);
218 return 1;
220 AROS_USERFUNC_EXIT
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))
227 AROS_USERFUNC_INIT
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");
236 return 0;
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,
245 return 1;
247 AROS_USERFUNC_EXIT
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))
254 AROS_USERFUNC_INIT
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");
263 return 0;
266 nmi_src = (struct acpi_table_nmi_src *) table_hook->header;
268 return 1;
270 AROS_USERFUNC_EXIT
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))
277 AROS_USERFUNC_INIT
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");
286 return 0;
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");
294 return -1;
297 rkprintf("[Kernel] (HOOK) ACPI_hook_Table_HPET_Parse: INFORMATION - HPET id: %d @ %p\n", hpet_tbl->id, hpet_tbl->addr.addrl);
299 return 1;
301 AROS_USERFUNC_EXIT
304 /************************************************************************************************/