added a lot of printk output to ease writing of emulator
[linux-2.4.21-pre4.git] / arch / x86_64 / kernel / acpitable.c
1 /*
2  *  acpitable.c - x86-64-specific ACPI (1.0 & 2.0) boot-time initialization
3  *
4  *  Copyright (C) 1999 Andrew Henroid
5  *  Copyright (C) 2001 Richard Schaal
6  *  Copyright (C) 2001 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
7  *  Copyright (C) 2001 Jun Nakajima <jun.nakajima@intel.com>
8  *  Copyright (C) 2001 Arjan van de Ven <arjanv@redhat.com>
9  *  Copyright (C) 2002 Vojtech Pavlik <vojtech@suse.cz>
10  */
11
12 #include <linux/config.h>
13 #include <linux/kernel.h>
14 #include <linux/init.h>
15 #include <linux/types.h>
16 #include <linux/stddef.h>
17 #include <linux/slab.h>
18 #include <linux/pci.h>
19 #include <asm/mpspec.h>
20 #include <asm/io.h>
21 #include <asm/apic.h>
22 #include <asm/apicdef.h>
23 #include <asm/page.h>
24 #include <asm/pgtable.h>
25 #include <asm/fixmap.h>
26
27 #include "acpitable.h"
28
29 static acpi_table_handler acpi_boot_ops[ACPI_TABLE_COUNT];
30
31 extern unsigned long end_pfn;
32 static inline int bad_ptr(void *p) 
33
34         if ((unsigned long)p  >> PAGE_SHIFT >= end_pfn) 
35                 return 1; 
36         return 0;       
37
38
39 /*
40  * Checksum an ACPI table.
41  */
42
43 static unsigned char __init acpi_checksum(void *buffer, int length)
44 {
45         unsigned char sum = 0;
46         while (length--)
47                 sum += *(unsigned char *)buffer++;
48         return sum;
49 }
50
51 /*
52  * Print an ACPI table header for debugging.
53  */
54
55 static char __init *acpi_kill_spaces(char *t, char *s, int m)
56 {
57         int l = strnlen(s, m);
58         strncpy(t, s, m);
59         t[l] = 0;
60         while (l > 0 && (t[l - 1] == ' ' || t[l - 1] == '\t')) t[--l] = 0;
61         while (t[0] == ' ' || t[0] == '\t') t++;
62         return t;
63 }
64
65 static void __init acpi_print_table_header(struct acpi_table_header * header)
66 {
67         char oem[7], id[9];
68
69         printk(KERN_INFO "acpi: %.4s rev: %d oem: %s id: %s build: %d.%d\n",
70                 header->signature, header->revision, acpi_kill_spaces(oem, header->oem_id, 6),
71                 acpi_kill_spaces(id, header->oem_table_id, 8), header->oem_revision >> 16,
72                 header->oem_revision & 0xffff);
73 }
74
75 /*
76  * Search a block of memory for the RSDP signature
77  */
78
79 static void* __init acpi_tb_scan_memory_for_rsdp(void *address, int length)
80 {
81         u32 offset = 0;
82
83         while (offset < length) {
84                 if (strncmp(address, "RSD PTR ", 8) == 0 &&
85                     acpi_checksum(address, RSDP_CHECKSUM_LENGTH) == 0) {
86                         printk(KERN_INFO "acpi: RSDP found at address %p\n", address);
87                         return address;
88                 }
89                 offset += RSDP_SCAN_STEP;
90                 address += RSDP_SCAN_STEP;
91         }
92         return NULL;
93 }
94
95 /*
96  * Search lower 1_mbyte of memory for the root system descriptor
97  * pointer structure. If it is found, set *RSDP to point to it.
98  */
99
100 static struct acpi_table_rsdp* __init acpi_find_root_pointer(void)
101 {
102         struct acpi_table_rsdp *rsdp;
103
104         if ((rsdp = acpi_tb_scan_memory_for_rsdp(__va(LO_RSDP_WINDOW_BASE), LO_RSDP_WINDOW_SIZE)))
105                 return rsdp;
106
107         if ((rsdp = acpi_tb_scan_memory_for_rsdp(__va(HI_RSDP_WINDOW_BASE), HI_RSDP_WINDOW_SIZE)))
108                 return rsdp;
109
110         return NULL;
111 }
112
113 static int __init acpi_process_table(u64 table)
114 {
115         struct acpi_table_header *header;
116         int type;
117
118         header = __va(table);
119
120         acpi_print_table_header(header);
121
122         if (acpi_checksum(header, header->length)) {
123                 printk(KERN_WARNING "acpi: ACPI table at %#lx has invalid checksum.\n", table);
124                 return -1;
125         }
126
127         for (type = 0; type < ACPI_TABLE_COUNT; type++)
128                 if (!strncmp(header->signature, acpi_table_signatures[type], 4))
129                         break;
130
131         if (type == ACPI_TABLE_COUNT || !acpi_boot_ops[type])
132                 return 0;
133
134         return acpi_boot_ops[type](header, table);
135 }
136
137 static int __init acpi_tables_init(void)
138 {
139         struct acpi_table_rsdp *rsdp;
140         struct acpi_table_xsdt *xsdt = NULL;
141         struct acpi_table_rsdt *rsdt = NULL;
142         char oem[7];
143         int i;
144
145         if (!(rsdp = acpi_find_root_pointer())) {
146                 printk(KERN_ERR "acpi: Couldn't find ACPI root pointer!\n");
147                 return -1;
148         }
149
150         printk(KERN_INFO "acpi: RSDP rev: %d oem: %s\n",
151                 rsdp->revision, acpi_kill_spaces(oem, rsdp->oem_id, 6));
152
153         if (!acpi_checksum(rsdp, RSDP2_CHECKSUM_LENGTH)
154                 && rsdp->length >= RSDP2_CHECKSUM_LENGTH) {     /* ACPI 2.0 might be present */
155                 xsdt = __va(rsdp->xsdt_address);
156                 if (bad_ptr(xsdt))
157                         return -1; 
158                 if (!strncmp(xsdt->header.signature, "XSDT", 4)) {
159                         acpi_print_table_header(&xsdt->header);
160                         for (i = 0; i < (xsdt->header.length - sizeof(struct acpi_table_header)) / sizeof(u64); i++)
161                                 if (acpi_process_table(xsdt->entry[i]))
162                                         return -1;
163                         return 0;
164                 }
165         }
166
167         rsdt = __va(rsdp->rsdt_address);
168         if (bad_ptr(rsdt))
169                 return -1;
170         if (!strncmp(rsdt->header.signature, "RSDT", 4)) {
171                 acpi_print_table_header(&rsdt->header);
172                 for (i = 0; i < (rsdt->header.length - sizeof(struct acpi_table_header)) / sizeof(u32); i++)
173                         if (acpi_process_table(rsdt->entry[i]))
174                                 return -1;
175                 return 0;
176         }
177
178         printk(KERN_WARNING "acpi: No ACPI table directory found.\n");
179         return -1;
180 }
181
182 static void __init acpi_parse_lapic(struct acpi_table_lapic *local_apic)
183 {
184         printk(KERN_INFO "acpi: LAPIC acpi_id: %d id: %d enabled: %d\n",
185                 local_apic->acpi_id, local_apic->id, local_apic->flags.enabled);
186 }
187
188 static void __init acpi_parse_ioapic(struct acpi_table_ioapic *ioapic)
189 {
190         printk(KERN_INFO "acpi: IOAPIC id: %d address: %#x global_irq_base: %#x\n",
191                 ioapic->id, ioapic->address, ioapic->global_irq_base);
192 }
193
194 static void __init acpi_parse_int_src_ovr(struct acpi_table_int_src_ovr *intsrc)
195 {
196         printk(KERN_INFO "acpi: INT_SRC_OVR bus: %d irq: %d global_irq: %d polarity: %d trigger: %d\n",
197                 intsrc->bus, intsrc->bus_irq, intsrc->global_irq, intsrc->flags.polarity, intsrc->flags.trigger);
198 }
199
200 static void __init acpi_parse_nmi_src(struct acpi_table_nmi_src *nmisrc)
201 {
202         printk(KERN_INFO "acpi: NMI_SRC polarity: %d trigger: %d global_irq: %d\n",
203                 nmisrc->flags.polarity, nmisrc->flags.trigger, nmisrc->global_irq);
204 }
205
206 static void __init acpi_parse_lapic_nmi(struct acpi_table_lapic_nmi *localnmi)
207 {
208         printk(KERN_INFO "acpi: LAPIC_NMI acpi_id: %d polarity: %d trigger: %d lint: %d\n",
209                 localnmi->acpi_id, localnmi->flags.polarity, localnmi->flags.trigger, localnmi->lint);
210 }
211
212 static void __init acpi_parse_lapic_addr_ovr(struct acpi_table_lapic_addr_ovr *lapic_addr_ovr)
213 {
214         printk(KERN_INFO "acpi: LAPIC_ADDR_OVR address: %#lx\n",
215                 (unsigned long) lapic_addr_ovr->address);
216 }
217
218 static void __init acpi_parse_plat_int_src(struct acpi_table_plat_int_src *plintsrc)
219 {
220         printk(KERN_INFO "acpi: PLAT_INT_SRC polarity: %d trigger: %d type: %d id: %d eid: %d iosapic_vector: %#x global_irq: %d\n",
221                 plintsrc->flags.polarity, plintsrc->flags.trigger, plintsrc->type, plintsrc->id, plintsrc->eid,
222                 plintsrc->iosapic_vector, plintsrc->global_irq);
223 }
224
225 static int __init acpi_parse_madt(struct acpi_table_header *header, unsigned long phys)
226 {
227
228         struct acpi_table_madt *madt;
229         struct acpi_madt_entry_header *entry_header;
230         int table_size;
231
232         madt = __va(phys);
233         table_size = header->length - sizeof(*madt);
234         entry_header = (void *)madt + sizeof(*madt);
235
236         while (entry_header && table_size > 0) {
237
238                 switch (entry_header->type) {
239                         case ACPI_MADT_LAPIC:
240                                 acpi_parse_lapic((void *) entry_header);
241                                 break;
242                         case ACPI_MADT_IOAPIC:
243                                 acpi_parse_ioapic((void *) entry_header);
244                                 break;
245                         case ACPI_MADT_INT_SRC_OVR:
246                                 acpi_parse_int_src_ovr((void *) entry_header);
247                                 break;
248                         case ACPI_MADT_NMI_SRC:
249                                 acpi_parse_nmi_src((void *) entry_header);
250                                 break;
251                         case ACPI_MADT_LAPIC_NMI:
252                                 acpi_parse_lapic_nmi((void *) entry_header);
253                                 break;
254                         case ACPI_MADT_LAPIC_ADDR_OVR:
255                                 acpi_parse_lapic_addr_ovr((void *) entry_header);
256                                 break;
257                         case ACPI_MADT_PLAT_INT_SRC:
258                                 acpi_parse_plat_int_src((void *) entry_header);
259                                 break;
260                         default:
261                                 printk(KERN_WARNING "acpi: Unsupported MADT entry type 0x%x\n", entry_header->type);
262                                 break;
263                 }
264
265                 table_size -= entry_header->length;
266                 entry_header = (void *) entry_header + entry_header->length;
267         }
268
269         printk(KERN_INFO "acpi: Local APIC address %#x\n", madt->lapic_address);
270
271         return 0;
272 }
273
274 static int __init acpi_parse_hpet(struct acpi_table_header *header, unsigned long phys)
275 {
276         struct acpi_table_hpet *hpet_tbl;
277
278         hpet_tbl = __va(phys);
279
280         if (hpet_tbl->addr.space_id != ACPI_SPACE_MEM) {
281                 printk(KERN_WARNING "acpi: HPET timers must be located in memory.\n");
282                 return -1;
283         }
284
285         hpet_address = hpet_tbl->addr.addrl | ((long) hpet_tbl->addr.addrh << 32);
286
287         printk(KERN_INFO "acpi: HPET id: %#x base: %#lx\n", hpet_tbl->id, hpet_address);
288
289         return 0;
290 }
291
292 /*
293  * Configure the processor info using MADT in the ACPI tables. If we fail to
294  * configure that, then we use the MPS tables.
295  */
296
297 void __init config_acpi_tables(void)
298 {
299         acpi_boot_ops[ACPI_APIC] = acpi_parse_madt;
300         acpi_boot_ops[ACPI_HPET] = acpi_parse_hpet;
301
302         if (acpi_tables_init())
303                 printk(KERN_ERR "acpi: Init failed.\n");
304 }