1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30#include <linux/config.h>
31#include <linux/kernel.h>
32#include <linux/init.h>
33#include <linux/types.h>
34#include <linux/stddef.h>
35#include <linux/slab.h>
36#include <linux/pci.h>
37#include <asm/mpspec.h>
38#include <asm/io.h>
39#include <asm/apic.h>
40#include <asm/apicdef.h>
41#include <asm/page.h>
42#include <asm/pgtable.h>
43
44#include "acpitable.h"
45
46static acpi_table_handler acpi_boot_ops[ACPI_TABLE_COUNT];
47
48
49static unsigned char __init
50acpi_checksum(void *buffer, int length)
51{
52 int i;
53 unsigned char *bytebuffer;
54 unsigned char sum = 0;
55
56 if (!buffer || length <= 0)
57 return 0;
58
59 bytebuffer = (unsigned char *) buffer;
60
61 for (i = 0; i < length; i++)
62 sum += *(bytebuffer++);
63
64 return sum;
65}
66
67static void __init
68acpi_print_table_header(acpi_table_header * header)
69{
70 if (!header)
71 return;
72
73 printk(KERN_INFO "ACPI table found: %.4s v%d [%.6s %.8s %d.%d]\n",
74 header->signature, header->revision, header->oem_id,
75 header->oem_table_id, header->oem_revision >> 16,
76 header->oem_revision & 0xffff);
77
78 return;
79}
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94static void *__init
95acpi_tb_scan_memory_for_rsdp(void *address, int length)
96{
97 u32 offset;
98
99 if (length <= 0)
100 return NULL;
101
102
103
104 offset = 0;
105
106 while (offset < length) {
107
108 if (strncmp(address, RSDP_SIG, sizeof(RSDP_SIG) - 1) == 0 &&
109 acpi_checksum(address, RSDP_CHECKSUM_LENGTH) == 0) {
110
111 printk(KERN_INFO "ACPI: RSDP located at physical address %p\n",
112 address);
113 return address;
114 }
115 offset += RSDP_SCAN_STEP;
116 address += RSDP_SCAN_STEP;
117 }
118
119
120 printk(KERN_INFO "ACPI: Searched entire block, no RSDP was found.\n");
121 return NULL;
122}
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141static struct acpi_table_rsdp * __init
142acpi_find_root_pointer(void)
143{
144 struct acpi_table_rsdp * rsdp;
145
146
147
148
149
150
151
152 rsdp = acpi_tb_scan_memory_for_rsdp(__va(LO_RSDP_WINDOW_BASE),
153 LO_RSDP_WINDOW_SIZE);
154
155 if (rsdp)
156 return rsdp;
157
158
159
160
161 rsdp = acpi_tb_scan_memory_for_rsdp(__va(HI_RSDP_WINDOW_BASE),
162 HI_RSDP_WINDOW_SIZE);
163
164
165
166 if (rsdp)
167 return rsdp;
168
169 printk(KERN_ERR "ACPI: System description tables not found\n");
170 return NULL;
171}
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186static __init char *
187__va_range(unsigned long phys, unsigned long size)
188{
189 unsigned long base, offset, mapped_size;
190 int idx;
191
192 offset = phys & (PAGE_SIZE - 1);
193 mapped_size = PAGE_SIZE - offset;
194 set_fixmap(FIX_IO_APIC_BASE_END, phys);
195 base = fix_to_virt(FIX_IO_APIC_BASE_END);
196 dprintk("__va_range(0x%lx, 0x%lx): idx=%d mapped at %lx\n", phys, size,
197 FIX_IO_APIC_BASE_END, base);
198
199
200
201
202 idx = FIX_IO_APIC_BASE_END;
203 while (mapped_size < size) {
204 if (--idx < FIX_IO_APIC_BASE_0)
205 return 0;
206 phys += PAGE_SIZE;
207 set_fixmap(idx, phys);
208 mapped_size += PAGE_SIZE;
209 }
210
211 return ((unsigned char *) base + offset);
212}
213
214static int __init acpi_tables_init(void)
215{
216 int result = -ENODEV;
217 acpi_table_header *header = NULL;
218 struct acpi_table_rsdp *rsdp = NULL;
219 struct acpi_table_rsdt *rsdt = NULL;
220 struct acpi_table_rsdt saved_rsdt;
221 int tables = 0;
222 int type = 0;
223 int i = 0;
224
225
226 rsdp = (struct acpi_table_rsdp *) acpi_find_root_pointer();
227
228 if (!rsdp)
229 return -ENODEV;
230
231 printk(KERN_INFO "%.8s v%d [%.6s]\n", rsdp->signature, rsdp->revision,
232 rsdp->oem_id);
233
234 if (strncmp(rsdp->signature, RSDP_SIG,strlen(RSDP_SIG))) {
235 printk(KERN_WARNING "RSDP table signature incorrect\n");
236 return -EINVAL;
237 }
238
239 rsdt = (struct acpi_table_rsdt *)
240 __va_range(rsdp->rsdt_address, sizeof(struct acpi_table_rsdt));
241
242 if (!rsdt) {
243 printk(KERN_WARNING "ACPI: Invalid root system description tables (RSDT)\n");
244 return -ENODEV;
245 }
246
247 header = & rsdt->header;
248 acpi_print_table_header(header);
249
250 if (strncmp(header->signature, RSDT_SIG, strlen(RSDT_SIG))) {
251 printk(KERN_WARNING "ACPI: RSDT signature incorrect\n");
252 return -ENODEV;
253 }
254
255
256
257
258
259
260
261 tables = (header->length - sizeof(acpi_table_header)) / 4;
262
263 memcpy(&saved_rsdt, rsdt, sizeof(saved_rsdt));
264
265 if (saved_rsdt.header.length > sizeof(saved_rsdt)) {
266 printk(KERN_WARNING "ACPI: Too big length in RSDT: %d\n", saved_rsdt.header.length);
267 return -ENODEV;
268 }
269
270 for (i = 0; i < tables; i++) {
271
272 header = (acpi_table_header *)
273 __va_range(saved_rsdt.entry[i],
274 sizeof(acpi_table_header));
275 if (!header)
276 break;
277 header = (acpi_table_header *)
278 __va_range(saved_rsdt.entry[i], header->length);
279 if (!header)
280 break;
281
282 acpi_print_table_header(header);
283
284 if (acpi_checksum(header,header->length)) {
285 printk(KERN_WARNING "ACPI %s has invalid checksum\n",
286 acpi_table_signatures[i]);
287 continue;
288 }
289
290 for (type = 0; type < ACPI_TABLE_COUNT; type++)
291 if (!strncmp((char *) &header->signature,
292 acpi_table_signatures[type],strlen(acpi_table_signatures[type])))
293 break;
294
295 if (type >= ACPI_TABLE_COUNT) {
296 printk(KERN_WARNING "ACPI: Unsupported table %.4s\n",
297 header->signature);
298 continue;
299 }
300
301
302 if (!acpi_boot_ops[type])
303 continue;
304
305 result = acpi_boot_ops[type] (header,
306 (unsigned long) saved_rsdt.
307 entry[i]);
308 }
309
310 return result;
311}
312
313static int total_cpus __initdata = 0;
314int have_acpi_tables;
315
316extern void __init MP_processor_info(struct mpc_config_processor *);
317
318static void __init
319acpi_parse_lapic(struct acpi_table_lapic *local_apic)
320{
321 struct mpc_config_processor proc_entry;
322 int ix = 0;
323
324 if (!local_apic)
325 return;
326
327 printk(KERN_INFO "LAPIC (acpi_id[0x%04x] id[0x%x] enabled[%d])\n",
328 local_apic->acpi_id, local_apic->id, local_apic->flags.enabled);
329
330 printk(KERN_INFO "CPU %d (0x%02x00)", total_cpus, local_apic->id);
331
332 if (local_apic->flags.enabled) {
333 printk(" enabled");
334 ix = local_apic->id;
335 if (ix >= MAX_APICS) {
336 printk(KERN_WARNING
337 "Processor #%d INVALID - (Max ID: %d).\n", ix,
338 MAX_APICS);
339 return;
340 }
341
342
343
344
345
346 proc_entry.mpc_type = MP_PROCESSOR;
347 proc_entry.mpc_apicid = local_apic->id;
348 proc_entry.mpc_cpuflag = CPU_ENABLED;
349 if (proc_entry.mpc_apicid == boot_cpu_physical_apicid) {
350 printk(" (BSP)");
351 proc_entry.mpc_cpuflag |= CPU_BOOTPROCESSOR;
352 }
353 proc_entry.mpc_cpufeature =
354 (boot_cpu_data.x86 << 8) |
355 (boot_cpu_data.x86_model << 4) |
356 boot_cpu_data.x86_mask;
357 proc_entry.mpc_featureflag = boot_cpu_data.x86_capability[0];
358 proc_entry.mpc_reserved[0] = 0;
359 proc_entry.mpc_reserved[1] = 0;
360 proc_entry.mpc_apicver = 0x10;
361 MP_processor_info(&proc_entry);
362 } else {
363 printk(" disabled");
364 }
365 printk("\n");
366
367 total_cpus++;
368 return;
369}
370
371static void __init
372acpi_parse_ioapic(struct acpi_table_ioapic *ioapic)
373{
374
375 if (!ioapic)
376 return;
377
378 printk(KERN_INFO
379 "IOAPIC (id[0x%x] address[0x%x] global_irq_base[0x%x])\n",
380 ioapic->id, ioapic->address, ioapic->global_irq_base);
381
382 if (nr_ioapics >= MAX_IO_APICS) {
383 printk(KERN_WARNING
384 "Max # of I/O APICs (%d) exceeded (found %d).\n",
385 MAX_IO_APICS, nr_ioapics);
386
387 }
388}
389
390
391
392
393
394static void __init
395acpi_parse_int_src_ovr(struct acpi_table_int_src_ovr *intsrc)
396{
397 if (!intsrc)
398 return;
399
400 printk(KERN_INFO
401 "INT_SRC_OVR (bus[%d] irq[0x%x] global_irq[0x%x] polarity[0x%x] trigger[0x%x])\n",
402 intsrc->bus, intsrc->bus_irq, intsrc->global_irq,
403 intsrc->flags.polarity, intsrc->flags.trigger);
404}
405
406
407
408
409
410
411static void __init acpi_parse_nmi_src(struct acpi_table_nmi_src *nmisrc)
412{
413 if (!nmisrc)
414 return;
415
416 printk(KERN_INFO
417 "NMI_SRC (polarity[0x%x] trigger[0x%x] global_irq[0x%x])\n",
418 nmisrc->flags.polarity, nmisrc->flags.trigger,
419 nmisrc->global_irq);
420
421}
422static void __init
423acpi_parse_lapic_nmi(struct acpi_table_lapic_nmi *localnmi)
424{
425 if (!localnmi)
426 return;
427
428 printk(KERN_INFO
429 "LAPIC_NMI (acpi_id[0x%04x] polarity[0x%x] trigger[0x%x] lint[0x%x])\n",
430 localnmi->acpi_id, localnmi->flags.polarity,
431 localnmi->flags.trigger, localnmi->lint);
432}
433static void __init
434acpi_parse_lapic_addr_ovr(struct acpi_table_lapic_addr_ovr *lapic_addr_ovr)
435{
436 if (!lapic_addr_ovr)
437 return;
438
439 printk(KERN_INFO "LAPIC_ADDR_OVR (address[0x%lx])\n",
440 (unsigned long) lapic_addr_ovr->address);
441
442}
443
444static void __init
445acpi_parse_plat_int_src(struct acpi_table_plat_int_src *plintsrc)
446{
447 if (!plintsrc)
448 return;
449
450 printk(KERN_INFO
451 "PLAT_INT_SRC (polarity[0x%x] trigger[0x%x] type[0x%x] id[0x%04x] eid[0x%x] iosapic_vector[0x%x] global_irq[0x%x]\n",
452 plintsrc->flags.polarity, plintsrc->flags.trigger,
453 plintsrc->type, plintsrc->id, plintsrc->eid,
454 plintsrc->iosapic_vector, plintsrc->global_irq);
455}
456static int __init
457acpi_parse_madt(acpi_table_header * header, unsigned long phys)
458{
459
460 struct acpi_table_madt *madt;
461 acpi_madt_entry_header *entry_header;
462 int table_size;
463
464 madt = (struct acpi_table_madt *) __va_range(phys, header->length);
465
466 if (!madt)
467 return -EINVAL;
468
469 table_size = (int) (header->length - sizeof(*madt));
470 entry_header =
471 (acpi_madt_entry_header *) ((void *) madt + sizeof(*madt));
472
473 while (entry_header && (table_size > 0)) {
474 switch (entry_header->type) {
475 case ACPI_MADT_LAPIC:
476 acpi_parse_lapic((struct acpi_table_lapic *)
477 entry_header);
478 break;
479 case ACPI_MADT_IOAPIC:
480 acpi_parse_ioapic((struct acpi_table_ioapic *)
481 entry_header);
482 break;
483 case ACPI_MADT_INT_SRC_OVR:
484 acpi_parse_int_src_ovr((struct acpi_table_int_src_ovr *)
485 entry_header);
486 break;
487 case ACPI_MADT_NMI_SRC:
488 acpi_parse_nmi_src((struct acpi_table_nmi_src *)
489 entry_header);
490 break;
491 case ACPI_MADT_LAPIC_NMI:
492 acpi_parse_lapic_nmi((struct acpi_table_lapic_nmi *)
493 entry_header);
494 break;
495 case ACPI_MADT_LAPIC_ADDR_OVR:
496 acpi_parse_lapic_addr_ovr((struct
497 acpi_table_lapic_addr_ovr *)
498 entry_header);
499 break;
500 case ACPI_MADT_PLAT_INT_SRC:
501 acpi_parse_plat_int_src((struct acpi_table_plat_int_src
502 *) entry_header);
503 break;
504 default:
505 printk(KERN_WARNING
506 "Unsupported MADT entry type 0x%x\n",
507 entry_header->type);
508 break;
509 }
510 table_size -= entry_header->length;
511 entry_header =
512 (acpi_madt_entry_header *) ((void *) entry_header +
513 entry_header->length);
514 }
515
516 if (!total_cpus) {
517 printk("ACPI: No Processors found in the APCI table.\n");
518 return -EINVAL;
519 }
520
521 printk(KERN_INFO "%d CPUs total\n", total_cpus);
522
523 if (madt->lapic_address)
524 mp_lapic_addr = madt->lapic_address;
525 else
526 mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
527
528 printk(KERN_INFO "Local APIC address %x\n", madt->lapic_address);
529
530 return 0;
531}
532
533extern int enable_acpi_smp_table;
534
535
536
537
538
539void __init
540config_acpi_tables(void)
541{
542
543 memset(&acpi_boot_ops, 0, sizeof(acpi_boot_ops));
544 acpi_boot_ops[ACPI_APIC] = acpi_parse_madt;
545
546
547
548
549
550 if (enable_acpi_smp_table && !acpi_tables_init()) {
551 have_acpi_tables = 1;
552 printk("Enabling the CPU's according to the ACPI table\n");
553 }
554}
555