Blame view

drivers/acpi/tables.c 21.4 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  /*
   *  acpi_tables.c - ACPI Boot-Time Table Parsing
   *
   *  Copyright (C) 2001 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
   *
   * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   *
   *  This program is free software; you can redistribute it and/or modify
   *  it under the terms of the GNU General Public License as published by
   *  the Free Software Foundation; either version 2 of the License, or
   *  (at your option) any later version.
   *
   *  This program is distributed in the hope that it will be useful,
   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   *  GNU General Public License for more details.
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
18
19
20
   * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   *
   */
07f438df2   Hanjun Guo   ACPI / table: Use...
21
22
  /* Uncomment next line to get verbose printout */
  /* #define DEBUG */
730bf5ebb   Hanjun Guo   ACPI / tables: Re...
23
  #define pr_fmt(fmt) "ACPI: " fmt
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
24
25
  #include <linux/init.h>
  #include <linux/kernel.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
26
27
28
29
30
31
32
  #include <linux/smp.h>
  #include <linux/string.h>
  #include <linux/types.h>
  #include <linux/irq.h>
  #include <linux/errno.h>
  #include <linux/acpi.h>
  #include <linux/bootmem.h>
5ae74f2cc   Lv Zheng   ACPI / tables: Mo...
33
34
  #include <linux/earlycpio.h>
  #include <linux/memblock.h>
da3d3f98d   Aleksey Makarov   ACPI / tables: ta...
35
  #include <linux/initrd.h>
c85cc817e   Lv Zheng   ACPI / OSL: Add s...
36
  #include "internal.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
37

74216699d   Rafael J. Wysocki   ACPI / tables: Fi...
38
39
40
  #ifdef CONFIG_ACPI_CUSTOM_DSDT
  #include CONFIG_ACPI_CUSTOM_DSDT_FILE
  #endif
04348e69e   Len Brown   [ACPI] reduce ker...
41
  #define ACPI_MAX_TABLES		128
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
42

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
43
44
  static char *mps_inti_flags_polarity[] = { "dfl", "high", "res", "low" };
  static char *mps_inti_flags_trigger[] = { "dfl", "edge", "res", "level" };
ad71860a1   Alexey Starikovskiy   ACPICA: minimal p...
45
  static struct acpi_table_desc initial_tables[ACPI_MAX_TABLES] __initdata;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
46

4e381a4f0   Len Brown   Revert "ACPI: par...
47
  static int acpi_apic_instance __initdata;
a1fdcc0d2   Len Brown   ACPI: Add support...
48

4fc0a7e88   Lv Zheng   ACPI: Fix x86 reg...
49
50
51
52
53
  /*
   * Disable table checksum verification for the early stage due to the size
   * limitation of the current x86 early mapping implementation.
   */
  static bool acpi_verify_table_checksum __initdata = false;
a1fdcc0d2   Len Brown   ACPI: Add support...
54
  void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
55
56
57
58
59
  {
  	if (!header)
  		return;
  
  	switch (header->type) {
5f3b1a8b6   Alexey Starikovskiy   ACPICA: Remove du...
60
  	case ACPI_MADT_TYPE_LOCAL_APIC:
4be44fcd3   Len Brown   [ACPI] Lindent al...
61
  		{
5f3b1a8b6   Alexey Starikovskiy   ACPICA: Remove du...
62
63
  			struct acpi_madt_local_apic *p =
  			    (struct acpi_madt_local_apic *)header;
07f438df2   Hanjun Guo   ACPI / table: Use...
64
65
66
67
  			pr_debug("LAPIC (acpi_id[0x%02x] lapic_id[0x%02x] %s)
  ",
  				 p->processor_id, p->id,
  				 (p->lapic_flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled");
4be44fcd3   Len Brown   [ACPI] Lindent al...
68
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
69
  		break;
7237d3de7   Suresh Siddha   x86, ACPI: add su...
70
71
72
73
  	case ACPI_MADT_TYPE_LOCAL_X2APIC:
  		{
  			struct acpi_madt_local_x2apic *p =
  			    (struct acpi_madt_local_x2apic *)header;
07f438df2   Hanjun Guo   ACPI / table: Use...
74
75
76
77
  			pr_debug("X2APIC (apic_id[0x%02x] uid[0x%02x] %s)
  ",
  				 p->local_apic_id, p->uid,
  				 (p->lapic_flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled");
7237d3de7   Suresh Siddha   x86, ACPI: add su...
78
79
  		}
  		break;
5f3b1a8b6   Alexey Starikovskiy   ACPICA: Remove du...
80
  	case ACPI_MADT_TYPE_IO_APIC:
4be44fcd3   Len Brown   [ACPI] Lindent al...
81
  		{
5f3b1a8b6   Alexey Starikovskiy   ACPICA: Remove du...
82
83
  			struct acpi_madt_io_apic *p =
  			    (struct acpi_madt_io_apic *)header;
07f438df2   Hanjun Guo   ACPI / table: Use...
84
85
86
  			pr_debug("IOAPIC (id[0x%02x] address[0x%08x] gsi_base[%d])
  ",
  				 p->id, p->address, p->global_irq_base);
4be44fcd3   Len Brown   [ACPI] Lindent al...
87
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
88
  		break;
5f3b1a8b6   Alexey Starikovskiy   ACPICA: Remove du...
89
  	case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
4be44fcd3   Len Brown   [ACPI] Lindent al...
90
  		{
5f3b1a8b6   Alexey Starikovskiy   ACPICA: Remove du...
91
92
  			struct acpi_madt_interrupt_override *p =
  			    (struct acpi_madt_interrupt_override *)header;
730bf5ebb   Hanjun Guo   ACPI / tables: Re...
93
94
95
96
97
  			pr_info("INT_SRC_OVR (bus %d bus_irq %d global_irq %d %s %s)
  ",
  				p->bus, p->source_irq, p->global_irq,
  				mps_inti_flags_polarity[p->inti_flags & ACPI_MADT_POLARITY_MASK],
  				mps_inti_flags_trigger[(p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2]);
5f3b1a8b6   Alexey Starikovskiy   ACPICA: Remove du...
98
99
  			if (p->inti_flags  &
  			    ~(ACPI_MADT_POLARITY_MASK | ACPI_MADT_TRIGGER_MASK))
730bf5ebb   Hanjun Guo   ACPI / tables: Re...
100
101
102
  				pr_info("INT_SRC_OVR unexpected reserved flags: 0x%x
  ",
  					p->inti_flags  &
5f3b1a8b6   Alexey Starikovskiy   ACPICA: Remove du...
103
  					~(ACPI_MADT_POLARITY_MASK | ACPI_MADT_TRIGGER_MASK));
4be44fcd3   Len Brown   [ACPI] Lindent al...
104
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
105
  		break;
5f3b1a8b6   Alexey Starikovskiy   ACPICA: Remove du...
106
  	case ACPI_MADT_TYPE_NMI_SOURCE:
4be44fcd3   Len Brown   [ACPI] Lindent al...
107
  		{
5f3b1a8b6   Alexey Starikovskiy   ACPICA: Remove du...
108
109
  			struct acpi_madt_nmi_source *p =
  			    (struct acpi_madt_nmi_source *)header;
730bf5ebb   Hanjun Guo   ACPI / tables: Re...
110
111
112
113
114
  			pr_info("NMI_SRC (%s %s global_irq %d)
  ",
  				mps_inti_flags_polarity[p->inti_flags & ACPI_MADT_POLARITY_MASK],
  				mps_inti_flags_trigger[(p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2],
  				p->global_irq);
4be44fcd3   Len Brown   [ACPI] Lindent al...
115
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
116
  		break;
5f3b1a8b6   Alexey Starikovskiy   ACPICA: Remove du...
117
  	case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
4be44fcd3   Len Brown   [ACPI] Lindent al...
118
  		{
5f3b1a8b6   Alexey Starikovskiy   ACPICA: Remove du...
119
120
  			struct acpi_madt_local_apic_nmi *p =
  			    (struct acpi_madt_local_apic_nmi *)header;
730bf5ebb   Hanjun Guo   ACPI / tables: Re...
121
122
123
124
125
126
  			pr_info("LAPIC_NMI (acpi_id[0x%02x] %s %s lint[0x%x])
  ",
  				p->processor_id,
  				mps_inti_flags_polarity[p->inti_flags & ACPI_MADT_POLARITY_MASK	],
  				mps_inti_flags_trigger[(p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2],
  				p->lint);
7237d3de7   Suresh Siddha   x86, ACPI: add su...
127
128
129
130
131
132
133
134
135
136
137
  		}
  		break;
  
  	case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
  		{
  			u16 polarity, trigger;
  			struct acpi_madt_local_x2apic_nmi *p =
  			    (struct acpi_madt_local_x2apic_nmi *)header;
  
  			polarity = p->inti_flags & ACPI_MADT_POLARITY_MASK;
  			trigger = (p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2;
730bf5ebb   Hanjun Guo   ACPI / tables: Re...
138
139
140
141
142
143
  			pr_info("X2APIC_NMI (uid[0x%02x] %s %s lint[0x%x])
  ",
  				p->uid,
  				mps_inti_flags_polarity[polarity],
  				mps_inti_flags_trigger[trigger],
  				p->lint);
4be44fcd3   Len Brown   [ACPI] Lindent al...
144
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
145
  		break;
5f3b1a8b6   Alexey Starikovskiy   ACPICA: Remove du...
146
  	case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
4be44fcd3   Len Brown   [ACPI] Lindent al...
147
  		{
5f3b1a8b6   Alexey Starikovskiy   ACPICA: Remove du...
148
149
  			struct acpi_madt_local_apic_override *p =
  			    (struct acpi_madt_local_apic_override *)header;
730bf5ebb   Hanjun Guo   ACPI / tables: Re...
150
151
152
  			pr_info("LAPIC_ADDR_OVR (address[%p])
  ",
  				(void *)(unsigned long)p->address);
4be44fcd3   Len Brown   [ACPI] Lindent al...
153
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
154
  		break;
5f3b1a8b6   Alexey Starikovskiy   ACPICA: Remove du...
155
  	case ACPI_MADT_TYPE_IO_SAPIC:
4be44fcd3   Len Brown   [ACPI] Lindent al...
156
  		{
5f3b1a8b6   Alexey Starikovskiy   ACPICA: Remove du...
157
158
  			struct acpi_madt_io_sapic *p =
  			    (struct acpi_madt_io_sapic *)header;
07f438df2   Hanjun Guo   ACPI / table: Use...
159
160
161
162
  			pr_debug("IOSAPIC (id[0x%x] address[%p] gsi_base[%d])
  ",
  				 p->id, (void *)(unsigned long)p->address,
  				 p->global_irq_base);
4be44fcd3   Len Brown   [ACPI] Lindent al...
163
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
164
  		break;
5f3b1a8b6   Alexey Starikovskiy   ACPICA: Remove du...
165
  	case ACPI_MADT_TYPE_LOCAL_SAPIC:
4be44fcd3   Len Brown   [ACPI] Lindent al...
166
  		{
5f3b1a8b6   Alexey Starikovskiy   ACPICA: Remove du...
167
168
  			struct acpi_madt_local_sapic *p =
  			    (struct acpi_madt_local_sapic *)header;
07f438df2   Hanjun Guo   ACPI / table: Use...
169
170
171
172
  			pr_debug("LSAPIC (acpi_id[0x%02x] lsapic_id[0x%02x] lsapic_eid[0x%02x] %s)
  ",
  				 p->processor_id, p->id, p->eid,
  				 (p->lapic_flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled");
4be44fcd3   Len Brown   [ACPI] Lindent al...
173
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
174
  		break;
5f3b1a8b6   Alexey Starikovskiy   ACPICA: Remove du...
175
  	case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
4be44fcd3   Len Brown   [ACPI] Lindent al...
176
  		{
5f3b1a8b6   Alexey Starikovskiy   ACPICA: Remove du...
177
178
  			struct acpi_madt_interrupt_source *p =
  			    (struct acpi_madt_interrupt_source *)header;
730bf5ebb   Hanjun Guo   ACPI / tables: Re...
179
180
181
182
183
184
  			pr_info("PLAT_INT_SRC (%s %s type[0x%x] id[0x%04x] eid[0x%x] iosapic_vector[0x%x] global_irq[0x%x]
  ",
  				mps_inti_flags_polarity[p->inti_flags & ACPI_MADT_POLARITY_MASK],
  				mps_inti_flags_trigger[(p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2],
  				p->type, p->id, p->eid, p->io_sapic_vector,
  				p->global_irq);
4be44fcd3   Len Brown   [ACPI] Lindent al...
185
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
186
  		break;
4c1c8d7a7   Hanjun Guo   ACPI / table: Pri...
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
  	case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
  		{
  			struct acpi_madt_generic_interrupt *p =
  				(struct acpi_madt_generic_interrupt *)header;
  			pr_debug("GICC (acpi_id[0x%04x] address[%llx] MPIDR[0x%llx] %s)
  ",
  				 p->uid, p->base_address,
  				 p->arm_mpidr,
  				 (p->flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled");
  
  		}
  		break;
  
  	case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
  		{
  			struct acpi_madt_generic_distributor *p =
  				(struct acpi_madt_generic_distributor *)header;
  			pr_debug("GIC Distributor (gic_id[0x%04x] address[%llx] gsi_base[%d])
  ",
  				 p->gic_id, p->base_address,
  				 p->global_irq_base);
  		}
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
210
  	default:
730bf5ebb   Hanjun Guo   ACPI / tables: Re...
211
212
213
  		pr_warn("Found unsupported MADT entry (type = 0x%x)
  ",
  			header->type);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
214
215
216
  		break;
  	}
  }
9b3fedde2   Lukasz Anaczkowski   ACPI / tables: Ad...
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
  /**
   * acpi_parse_entries_array - for each proc_num find a suitable subtable
   *
   * @id: table id (for debugging purposes)
   * @table_size: single entry size
   * @table_header: where does the table start?
   * @proc: array of acpi_subtable_proc struct containing entry id
   *        and associated handler with it
   * @proc_num: how big proc is?
   * @max_entries: how many entries can we process?
   *
   * For each proc_num find a subtable with proc->id and run proc->handler
   * on it. Assumption is that there's only single handler for particular
   * entry id.
   *
   * On success returns sum of all matching entries for all proc handlers.
   * Otherwise, -ENODEV or -EINVAL is returned.
   */
  static int __init
  acpi_parse_entries_array(char *id, unsigned long table_size,
f08bb472b   Ashwin Chaugule   ACPI / table: Add...
237
  		struct acpi_table_header *table_header,
9b3fedde2   Lukasz Anaczkowski   ACPI / tables: Ad...
238
239
  		struct acpi_subtable_proc *proc, int proc_num,
  		unsigned int max_entries)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
240
  {
5f3b1a8b6   Alexey Starikovskiy   ACPICA: Remove du...
241
  	struct acpi_subtable_header *entry;
6eb87fed5   Len Brown   ACPI: acpi_table_...
242
  	unsigned long table_end;
9b3fedde2   Lukasz Anaczkowski   ACPI / tables: Ad...
243
  	int count = 0;
8726d4f44   Al Stone   ACPI / tables: fi...
244
  	int errs = 0;
9b3fedde2   Lukasz Anaczkowski   ACPI / tables: Ad...
245
  	int i;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
246

68ca40693   Len Brown   ACPI: delete the ...
247
  	if (acpi_disabled)
e5b8fc6ac   Len Brown   ACPI: check acpi_...
248
  		return -ENODEV;
9b3fedde2   Lukasz Anaczkowski   ACPI / tables: Ad...
249
  	if (!id)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
250
  		return -EINVAL;
f08bb472b   Ashwin Chaugule   ACPI / table: Add...
251
252
  	if (!table_size)
  		return -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
253

6eb87fed5   Len Brown   ACPI: acpi_table_...
254
  	if (!table_header) {
730bf5ebb   Hanjun Guo   ACPI / tables: Re...
255
256
  		pr_warn("%4.4s not present
  ", id);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
257
258
  		return -ENODEV;
  	}
6eb87fed5   Len Brown   ACPI: acpi_table_...
259
  	table_end = (unsigned long)table_header + table_header->length;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
260
261
  
  	/* Parse all entries looking for a match. */
5f3b1a8b6   Alexey Starikovskiy   ACPICA: Remove du...
262
  	entry = (struct acpi_subtable_header *)
6eb87fed5   Len Brown   ACPI: acpi_table_...
263
  	    ((unsigned long)table_header + table_size);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
264

5f3b1a8b6   Alexey Starikovskiy   ACPICA: Remove du...
265
  	while (((unsigned long)entry) + sizeof(struct acpi_subtable_header) <
6eb87fed5   Len Brown   ACPI: acpi_table_...
266
  	       table_end) {
9b3fedde2   Lukasz Anaczkowski   ACPI / tables: Ad...
267
268
269
270
271
272
  		if (max_entries && count >= max_entries)
  			break;
  
  		for (i = 0; i < proc_num; i++) {
  			if (entry->type != proc[i].id)
  				continue;
362414d9d   Dan Carpenter   ACPI / tables: te...
273
  			if (!proc[i].handler ||
8726d4f44   Al Stone   ACPI / tables: fi...
274
275
276
277
  			     (!errs && proc[i].handler(entry, table_end))) {
  				errs++;
  				continue;
  			}
369d913b2   Fenghua Yu   ACPI: Harden acpi...
278

fa162a05d   Al Stone   ACPI / tables: fi...
279
  			proc[i].count++;
9b3fedde2   Lukasz Anaczkowski   ACPI / tables: Ad...
280
  			break;
4ceacd02f   Tomasz Nowicki   ACPI / table: Alw...
281
  		}
9b3fedde2   Lukasz Anaczkowski   ACPI / tables: Ad...
282
283
  		if (i != proc_num)
  			count++;
4ceacd02f   Tomasz Nowicki   ACPI / table: Alw...
284

369d913b2   Fenghua Yu   ACPI: Harden acpi...
285
286
287
288
289
  		/*
  		 * If entry->length is 0, break from this loop to avoid
  		 * infinite loop.
  		 */
  		if (entry->length == 0) {
9b3fedde2   Lukasz Anaczkowski   ACPI / tables: Ad...
290
291
  			pr_err("[%4.4s:0x%02x] Invalid zero length
  ", id, proc->id);
f08bb472b   Ashwin Chaugule   ACPI / table: Add...
292
  			return -EINVAL;
369d913b2   Fenghua Yu   ACPI: Harden acpi...
293
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
294

5f3b1a8b6   Alexey Starikovskiy   ACPICA: Remove du...
295
  		entry = (struct acpi_subtable_header *)
4be44fcd3   Len Brown   [ACPI] Lindent al...
296
  		    ((unsigned long)entry + entry->length);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
297
  	}
f08bb472b   Ashwin Chaugule   ACPI / table: Add...
298

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
299
  	if (max_entries && count > max_entries) {
99b0efd7c   Al Stone   ACPI / tables: do...
300
301
302
  		pr_warn("[%4.4s:0x%02x] found the maximum %i entries
  ",
  			id, proc->id, count);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
303
  	}
8726d4f44   Al Stone   ACPI / tables: fi...
304
  	return errs ? -EINVAL : count;
f08bb472b   Ashwin Chaugule   ACPI / table: Add...
305
306
307
  }
  
  int __init
9b3fedde2   Lukasz Anaczkowski   ACPI / tables: Ad...
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
  acpi_parse_entries(char *id,
  			unsigned long table_size,
  			acpi_tbl_entry_handler handler,
  			struct acpi_table_header *table_header,
  			int entry_id, unsigned int max_entries)
  {
  	struct acpi_subtable_proc proc = {
  		.id		= entry_id,
  		.handler	= handler,
  	};
  
  	return acpi_parse_entries_array(id, table_size, table_header,
  			&proc, 1, max_entries);
  }
  
  int __init
  acpi_table_parse_entries_array(char *id,
f08bb472b   Ashwin Chaugule   ACPI / table: Add...
325
  			 unsigned long table_size,
9b3fedde2   Lukasz Anaczkowski   ACPI / tables: Ad...
326
  			 struct acpi_subtable_proc *proc, int proc_num,
f08bb472b   Ashwin Chaugule   ACPI / table: Add...
327
328
329
330
331
332
333
334
335
  			 unsigned int max_entries)
  {
  	struct acpi_table_header *table_header = NULL;
  	acpi_size tbl_size;
  	int count;
  	u32 instance = 0;
  
  	if (acpi_disabled)
  		return -ENODEV;
9b3fedde2   Lukasz Anaczkowski   ACPI / tables: Ad...
336
  	if (!id)
f08bb472b   Ashwin Chaugule   ACPI / table: Add...
337
338
339
340
341
342
343
344
345
346
347
  		return -EINVAL;
  
  	if (!strncmp(id, ACPI_SIG_MADT, 4))
  		instance = acpi_apic_instance;
  
  	acpi_get_table_with_size(id, instance, &table_header, &tbl_size);
  	if (!table_header) {
  		pr_warn("%4.4s not present
  ", id);
  		return -ENODEV;
  	}
9b3fedde2   Lukasz Anaczkowski   ACPI / tables: Ad...
348
349
  	count = acpi_parse_entries_array(id, table_size, table_header,
  			proc, proc_num, max_entries);
f08bb472b   Ashwin Chaugule   ACPI / table: Add...
350

369d913b2   Fenghua Yu   ACPI: Harden acpi...
351
  	early_acpi_os_unmap_memory((char *)table_header, tbl_size);
f08bb472b   Ashwin Chaugule   ACPI / table: Add...
352
  	return count;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
353
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
354
  int __init
9b3fedde2   Lukasz Anaczkowski   ACPI / tables: Ad...
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
  acpi_table_parse_entries(char *id,
  			unsigned long table_size,
  			int entry_id,
  			acpi_tbl_entry_handler handler,
  			unsigned int max_entries)
  {
  	struct acpi_subtable_proc proc = {
  		.id		= entry_id,
  		.handler	= handler,
  	};
  
  	return acpi_table_parse_entries_array(id, table_size, &proc, 1,
  						max_entries);
  }
  
  int __init
5f3b1a8b6   Alexey Starikovskiy   ACPICA: Remove du...
371
  acpi_table_parse_madt(enum acpi_madt_type id,
b43e1065c   Lv Zheng   ACPICA: Cleanup t...
372
  		      acpi_tbl_entry_handler handler, unsigned int max_entries)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
373
  {
6eb87fed5   Len Brown   ACPI: acpi_table_...
374
  	return acpi_table_parse_entries(ACPI_SIG_MADT,
4be44fcd3   Len Brown   [ACPI] Lindent al...
375
376
  					    sizeof(struct acpi_table_madt), id,
  					    handler, max_entries);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
377
  }
7f8f97c3c   Len Brown   ACPI: acpi_table_...
378
379
  /**
   * acpi_table_parse - find table with @id, run @handler on it
7f8f97c3c   Len Brown   ACPI: acpi_table_...
380
381
382
383
   * @id: table id to find
   * @handler: handler to run
   *
   * Scan the ACPI System Descriptor Table (STD) for a table matching @id,
f8a571b2a   tangchen   ACPI / tables: Re...
384
385
386
   * run @handler on it.
   *
   * Return 0 if table found, -errno if not.
7f8f97c3c   Len Brown   ACPI: acpi_table_...
387
   */
b43e1065c   Lv Zheng   ACPICA: Cleanup t...
388
  int __init acpi_table_parse(char *id, acpi_tbl_table_handler handler)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
389
  {
ceb6c4683   Alexey Starikovskiy   ACPICA: Remove du...
390
  	struct acpi_table_header *table = NULL;
7d97277b7   Yinghai Lu   acpi/x86: introdu...
391
  	acpi_size tbl_size;
a1fdcc0d2   Len Brown   ACPI: Add support...
392

68ca40693   Len Brown   ACPI: delete the ...
393
  	if (acpi_disabled)
e5b8fc6ac   Len Brown   ACPI: check acpi_...
394
  		return -ENODEV;
de2d1a7e9   tangchen   ACPI / tables: Ch...
395
  	if (!id || !handler)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
396
  		return -EINVAL;
a1fdcc0d2   Len Brown   ACPI: Add support...
397
  	if (strncmp(id, ACPI_SIG_MADT, 4) == 0)
7d97277b7   Yinghai Lu   acpi/x86: introdu...
398
  		acpi_get_table_with_size(id, acpi_apic_instance, &table, &tbl_size);
a1fdcc0d2   Len Brown   ACPI: Add support...
399
  	else
7d97277b7   Yinghai Lu   acpi/x86: introdu...
400
  		acpi_get_table_with_size(id, 0, &table, &tbl_size);
a1fdcc0d2   Len Brown   ACPI: Add support...
401

ceb6c4683   Alexey Starikovskiy   ACPICA: Remove du...
402
403
  	if (table) {
  		handler(table);
7d97277b7   Yinghai Lu   acpi/x86: introdu...
404
  		early_acpi_os_unmap_memory(table, tbl_size);
ceb6c4683   Alexey Starikovskiy   ACPICA: Remove du...
405
  		return 0;
7f8f97c3c   Len Brown   ACPI: acpi_table_...
406
  	} else
95df812db   Hanjun Guo   ACPI / table: Rep...
407
  		return -ENODEV;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
408
  }
a1fdcc0d2   Len Brown   ACPI: Add support...
409
410
411
412
413
414
415
416
  /* 
   * The BIOS is supposed to supply a single APIC/MADT,
   * but some report two.  Provide a knob to use either.
   * (don't you wish instance 0 and 1 were not the same?)
   */
  static void __init check_multiple_madt(void)
  {
  	struct acpi_table_header *table = NULL;
7d97277b7   Yinghai Lu   acpi/x86: introdu...
417
  	acpi_size tbl_size;
a1fdcc0d2   Len Brown   ACPI: Add support...
418

7d97277b7   Yinghai Lu   acpi/x86: introdu...
419
  	acpi_get_table_with_size(ACPI_SIG_MADT, 2, &table, &tbl_size);
a1fdcc0d2   Len Brown   ACPI: Add support...
420
  	if (table) {
730bf5ebb   Hanjun Guo   ACPI / tables: Re...
421
422
423
424
425
426
427
  		pr_warn("BIOS bug: multiple APIC/MADT found, using %d
  ",
  			acpi_apic_instance);
  		pr_warn("If \"acpi_apic_instance=%d\" works better, "
  			"notify linux-acpi@vger.kernel.org
  ",
  			acpi_apic_instance ? 0 : 2);
7d97277b7   Yinghai Lu   acpi/x86: introdu...
428
  		early_acpi_os_unmap_memory(table, tbl_size);
a1fdcc0d2   Len Brown   ACPI: Add support...
429
430
431
432
433
434
  
  	} else
  		acpi_apic_instance = 0;
  
  	return;
  }
5ae74f2cc   Lv Zheng   ACPI / tables: Mo...
435
436
437
438
439
440
441
  static void acpi_table_taint(struct acpi_table_header *table)
  {
  	pr_warn("Override [%4.4s-%8.8s], this is unsafe: tainting kernel
  ",
  		table->signature, table->oem_table_id);
  	add_taint(TAINT_OVERRIDDEN_ACPI_TABLE, LOCKDEP_NOW_UNRELIABLE);
  }
5d8813271   Lv Zheng   ACPI / tables: Co...
442
  #ifdef CONFIG_ACPI_TABLE_UPGRADE
5ae74f2cc   Lv Zheng   ACPI / tables: Mo...
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
  static u64 acpi_tables_addr;
  static int all_tables_size;
  
  /* Copied from acpica/tbutils.c:acpi_tb_checksum() */
  static u8 __init acpi_table_checksum(u8 *buffer, u32 length)
  {
  	u8 sum = 0;
  	u8 *end = buffer + length;
  
  	while (buffer < end)
  		sum = (u8) (sum + *(buffer++));
  	return sum;
  }
  
  /* All but ACPI_SIG_RSDP and ACPI_SIG_FACS: */
  static const char * const table_sigs[] = {
  	ACPI_SIG_BERT, ACPI_SIG_CPEP, ACPI_SIG_ECDT, ACPI_SIG_EINJ,
  	ACPI_SIG_ERST, ACPI_SIG_HEST, ACPI_SIG_MADT, ACPI_SIG_MSCT,
  	ACPI_SIG_SBST, ACPI_SIG_SLIT, ACPI_SIG_SRAT, ACPI_SIG_ASF,
  	ACPI_SIG_BOOT, ACPI_SIG_DBGP, ACPI_SIG_DMAR, ACPI_SIG_HPET,
  	ACPI_SIG_IBFT, ACPI_SIG_IVRS, ACPI_SIG_MCFG, ACPI_SIG_MCHI,
  	ACPI_SIG_SLIC, ACPI_SIG_SPCR, ACPI_SIG_SPMI, ACPI_SIG_TCPA,
  	ACPI_SIG_UEFI, ACPI_SIG_WAET, ACPI_SIG_WDAT, ACPI_SIG_WDDT,
  	ACPI_SIG_WDRT, ACPI_SIG_DSDT, ACPI_SIG_FADT, ACPI_SIG_PSDT,
  	ACPI_SIG_RSDT, ACPI_SIG_XSDT, ACPI_SIG_SSDT, NULL };
  
  #define ACPI_HEADER_SIZE sizeof(struct acpi_table_header)
5d8813271   Lv Zheng   ACPI / tables: Co...
470
471
472
  #define NR_ACPI_INITRD_TABLES 64
  static struct cpio_data __initdata acpi_initrd_files[NR_ACPI_INITRD_TABLES];
  static DECLARE_BITMAP(acpi_initrd_installed, NR_ACPI_INITRD_TABLES);
5ae74f2cc   Lv Zheng   ACPI / tables: Mo...
473
474
  
  #define MAP_CHUNK_SIZE   (NR_FIX_BTMAPS << PAGE_SHIFT)
da3d3f98d   Aleksey Makarov   ACPI / tables: ta...
475
  void __init acpi_table_upgrade(void)
5ae74f2cc   Lv Zheng   ACPI / tables: Mo...
476
  {
da3d3f98d   Aleksey Makarov   ACPI / tables: ta...
477
478
  	void *data = (void *)initrd_start;
  	size_t size = initrd_end - initrd_start;
5ae74f2cc   Lv Zheng   ACPI / tables: Mo...
479
480
481
482
483
484
485
486
  	int sig, no, table_nr = 0, total_offset = 0;
  	long offset = 0;
  	struct acpi_table_header *table;
  	char cpio_path[32] = "kernel/firmware/acpi/";
  	struct cpio_data file;
  
  	if (data == NULL || size == 0)
  		return;
5d8813271   Lv Zheng   ACPI / tables: Co...
487
  	for (no = 0; no < NR_ACPI_INITRD_TABLES; no++) {
5ae74f2cc   Lv Zheng   ACPI / tables: Mo...
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
  		file = find_cpio_data(cpio_path, data, size, &offset);
  		if (!file.data)
  			break;
  
  		data += offset;
  		size -= offset;
  
  		if (file.size < sizeof(struct acpi_table_header)) {
  			pr_err("ACPI OVERRIDE: Table smaller than ACPI header [%s%s]
  ",
  				cpio_path, file.name);
  			continue;
  		}
  
  		table = file.data;
  
  		for (sig = 0; table_sigs[sig]; sig++)
  			if (!memcmp(table->signature, table_sigs[sig], 4))
  				break;
  
  		if (!table_sigs[sig]) {
  			pr_err("ACPI OVERRIDE: Unknown signature [%s%s]
  ",
  				cpio_path, file.name);
  			continue;
  		}
  		if (file.size != table->length) {
  			pr_err("ACPI OVERRIDE: File length does not match table length [%s%s]
  ",
  				cpio_path, file.name);
  			continue;
  		}
  		if (acpi_table_checksum(file.data, table->length)) {
  			pr_err("ACPI OVERRIDE: Bad table checksum [%s%s]
  ",
  				cpio_path, file.name);
  			continue;
  		}
  
  		pr_info("%4.4s ACPI table found in initrd [%s%s][0x%x]
  ",
  			table->signature, cpio_path, file.name, table->length);
  
  		all_tables_size += table->length;
  		acpi_initrd_files[table_nr].data = file.data;
  		acpi_initrd_files[table_nr].size = file.size;
  		table_nr++;
  	}
  	if (table_nr == 0)
  		return;
  
  	acpi_tables_addr =
84b06ca31   Aleksey Makarov   ACPI / tables: mo...
540
  		memblock_find_in_range(0, ACPI_TABLE_UPGRADE_MAX_PHYS,
5ae74f2cc   Lv Zheng   ACPI / tables: Mo...
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
  				       all_tables_size, PAGE_SIZE);
  	if (!acpi_tables_addr) {
  		WARN_ON(1);
  		return;
  	}
  	/*
  	 * Only calling e820_add_reserve does not work and the
  	 * tables are invalid (memory got used) later.
  	 * memblock_reserve works as expected and the tables won't get modified.
  	 * But it's not enough on X86 because ioremap will
  	 * complain later (used by acpi_os_map_memory) that the pages
  	 * that should get mapped are not marked "reserved".
  	 * Both memblock_reserve and e820_add_region (via arch_reserve_mem_area)
  	 * works fine.
  	 */
  	memblock_reserve(acpi_tables_addr, all_tables_size);
  	arch_reserve_mem_area(acpi_tables_addr, all_tables_size);
  
  	/*
  	 * early_ioremap only can remap 256k one time. If we map all
  	 * tables one time, we will hit the limit. Need to map chunks
  	 * one by one during copying the same as that in relocate_initrd().
  	 */
  	for (no = 0; no < table_nr; no++) {
  		unsigned char *src_p = acpi_initrd_files[no].data;
  		phys_addr_t size = acpi_initrd_files[no].size;
  		phys_addr_t dest_addr = acpi_tables_addr + total_offset;
  		phys_addr_t slop, clen;
  		char *dest_p;
  
  		total_offset += size;
  
  		while (size) {
  			slop = dest_addr & ~PAGE_MASK;
  			clen = size;
  			if (clen > MAP_CHUNK_SIZE - slop)
  				clen = MAP_CHUNK_SIZE - slop;
ce0c1fcc7   Aleksey Makarov   ACPI / tables: ta...
578
579
  			dest_p = early_memremap(dest_addr & PAGE_MASK,
  						clen + slop);
5ae74f2cc   Lv Zheng   ACPI / tables: Mo...
580
  			memcpy(dest_p + slop, src_p, clen);
ce0c1fcc7   Aleksey Makarov   ACPI / tables: ta...
581
  			early_memunmap(dest_p, clen + slop);
5ae74f2cc   Lv Zheng   ACPI / tables: Mo...
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
  			src_p += clen;
  			dest_addr += clen;
  			size -= clen;
  		}
  	}
  }
  
  static acpi_status
  acpi_table_initrd_override(struct acpi_table_header *existing_table,
  			   acpi_physical_address *address, u32 *length)
  {
  	int table_offset = 0;
  	int table_index = 0;
  	struct acpi_table_header *table;
  	u32 table_length;
  
  	*length = 0;
  	*address = 0;
  	if (!acpi_tables_addr)
  		return AE_OK;
  
  	while (table_offset + ACPI_HEADER_SIZE <= all_tables_size) {
  		table = acpi_os_map_memory(acpi_tables_addr + table_offset,
  					   ACPI_HEADER_SIZE);
  		if (table_offset + table->length > all_tables_size) {
  			acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
  			WARN_ON(1);
  			return AE_OK;
  		}
  
  		table_length = table->length;
  
  		/* Only override tables matched */
5d8813271   Lv Zheng   ACPI / tables: Co...
615
616
617
  		if (memcmp(existing_table->signature, table->signature, 4) ||
  		    memcmp(table->oem_id, existing_table->oem_id,
  			   ACPI_OEM_ID_SIZE) ||
5ae74f2cc   Lv Zheng   ACPI / tables: Mo...
618
619
620
621
622
  		    memcmp(table->oem_table_id, existing_table->oem_table_id,
  			   ACPI_OEM_TABLE_ID_SIZE)) {
  			acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
  			goto next_table;
  		}
5d8813271   Lv Zheng   ACPI / tables: Co...
623
624
625
626
627
628
629
630
631
  		/*
  		 * Mark the table to avoid being used in
  		 * acpi_table_initrd_scan() and check the revision.
  		 */
  		if (test_and_set_bit(table_index, acpi_initrd_installed) ||
  		    existing_table->oem_revision >= table->oem_revision) {
  			acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
  			goto next_table;
  		}
5ae74f2cc   Lv Zheng   ACPI / tables: Mo...
632
633
634
  
  		*length = table_length;
  		*address = acpi_tables_addr + table_offset;
5d8813271   Lv Zheng   ACPI / tables: Co...
635
636
637
638
  		pr_info("Table Upgrade: override [%4.4s-%6.6s-%8.8s]
  ",
  			table->signature, table->oem_id,
  			table->oem_table_id);
5ae74f2cc   Lv Zheng   ACPI / tables: Mo...
639
  		acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
5ae74f2cc   Lv Zheng   ACPI / tables: Mo...
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
  		break;
  
  next_table:
  		table_offset += table_length;
  		table_index++;
  	}
  	return AE_OK;
  }
  
  static void __init acpi_table_initrd_scan(void)
  {
  	int table_offset = 0;
  	int table_index = 0;
  	u32 table_length;
  	struct acpi_table_header *table;
  
  	if (!acpi_tables_addr)
  		return;
  
  	while (table_offset + ACPI_HEADER_SIZE <= all_tables_size) {
  		table = acpi_os_map_memory(acpi_tables_addr + table_offset,
  					   ACPI_HEADER_SIZE);
  		if (table_offset + table->length > all_tables_size) {
  			acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
  			WARN_ON(1);
  			return;
  		}
  
  		table_length = table->length;
  
  		/* Skip RSDT/XSDT which should only be used for override */
5d8813271   Lv Zheng   ACPI / tables: Co...
671
  		if (ACPI_COMPARE_NAME(table->signature, ACPI_SIG_RSDT) ||
5ae74f2cc   Lv Zheng   ACPI / tables: Mo...
672
673
674
675
  		    ACPI_COMPARE_NAME(table->signature, ACPI_SIG_XSDT)) {
  			acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
  			goto next_table;
  		}
5d8813271   Lv Zheng   ACPI / tables: Co...
676
677
678
679
680
681
682
683
684
  		/*
  		 * Mark the table to avoid being used in
  		 * acpi_table_initrd_override(). Though this is not possible
  		 * because override is disabled in acpi_install_table().
  		 */
  		if (test_and_set_bit(table_index, acpi_initrd_installed)) {
  			acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
  			goto next_table;
  		}
5ae74f2cc   Lv Zheng   ACPI / tables: Mo...
685

5d8813271   Lv Zheng   ACPI / tables: Co...
686
687
688
689
  		pr_info("Table Upgrade: install [%4.4s-%6.6s-%8.8s]
  ",
  			table->signature, table->oem_id,
  			table->oem_table_id);
5ae74f2cc   Lv Zheng   ACPI / tables: Mo...
690
691
  		acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
  		acpi_install_table(acpi_tables_addr + table_offset, TRUE);
5ae74f2cc   Lv Zheng   ACPI / tables: Mo...
692
693
694
695
696
697
  next_table:
  		table_offset += table_length;
  		table_index++;
  	}
  }
  #else
5ae74f2cc   Lv Zheng   ACPI / tables: Mo...
698
699
700
701
702
703
704
705
706
707
708
709
710
  static acpi_status
  acpi_table_initrd_override(struct acpi_table_header *existing_table,
  			   acpi_physical_address *address,
  			   u32 *table_length)
  {
  	*table_length = 0;
  	*address = 0;
  	return AE_OK;
  }
  
  static void __init acpi_table_initrd_scan(void)
  {
  }
5d8813271   Lv Zheng   ACPI / tables: Co...
711
  #endif /* CONFIG_ACPI_TABLE_UPGRADE */
5ae74f2cc   Lv Zheng   ACPI / tables: Mo...
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
  
  acpi_status
  acpi_os_physical_table_override(struct acpi_table_header *existing_table,
  				acpi_physical_address *address,
  				u32 *table_length)
  {
  	return acpi_table_initrd_override(existing_table, address,
  					  table_length);
  }
  
  acpi_status
  acpi_os_table_override(struct acpi_table_header *existing_table,
  		       struct acpi_table_header **new_table)
  {
  	if (!existing_table || !new_table)
  		return AE_BAD_PARAMETER;
  
  	*new_table = NULL;
  
  #ifdef CONFIG_ACPI_CUSTOM_DSDT
  	if (strncmp(existing_table->signature, "DSDT", 4) == 0)
  		*new_table = (struct acpi_table_header *)AmlCode;
  #endif
  	if (*new_table != NULL)
  		acpi_table_taint(existing_table);
  	return AE_OK;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
739
740
741
742
743
  /*
   * acpi_table_init()
   *
   * find RSDP, find and checksum SDT/XSDT.
   * checksum all tables, print SDT/XSDT
5f3b1a8b6   Alexey Starikovskiy   ACPICA: Remove du...
744
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
745
746
   * result: sdt_entry[] is initialized
   */
4be44fcd3   Len Brown   [ACPI] Lindent al...
747
  int __init acpi_table_init(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
748
  {
9e3a9d1ed   Len Brown   ACPI: disable ACP...
749
  	acpi_status status;
4fc0a7e88   Lv Zheng   ACPI: Fix x86 reg...
750
751
752
753
754
755
756
757
758
  	if (acpi_verify_table_checksum) {
  		pr_info("Early table checksum verification enabled
  ");
  		acpi_gbl_verify_table_checksum = TRUE;
  	} else {
  		pr_info("Early table checksum verification disabled
  ");
  		acpi_gbl_verify_table_checksum = FALSE;
  	}
9e3a9d1ed   Len Brown   ACPI: disable ACP...
759
760
  	status = acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0);
  	if (ACPI_FAILURE(status))
95df812db   Hanjun Guo   ACPI / table: Rep...
761
  		return -EINVAL;
5ae74f2cc   Lv Zheng   ACPI / tables: Mo...
762
  	acpi_table_initrd_scan();
9e3a9d1ed   Len Brown   ACPI: disable ACP...
763

a1fdcc0d2   Len Brown   ACPI: Add support...
764
765
766
767
768
769
  	check_multiple_madt();
  	return 0;
  }
  
  static int __init acpi_parse_apic_instance(char *str)
  {
f0df2d6b5   Cyrill Gorcunov   acpi: add checkin...
770
771
  	if (!str)
  		return -EINVAL;
a1fdcc0d2   Len Brown   ACPI: Add support...
772

3d915894f   Christoph Jaeger   ACPI: use kstrto*...
773
774
  	if (kstrtoint(str, 0, &acpi_apic_instance))
  		return -EINVAL;
a1fdcc0d2   Len Brown   ACPI: Add support...
775

730bf5ebb   Hanjun Guo   ACPI / tables: Re...
776
777
  	pr_notice("Shall use APIC/MADT table %d
  ", acpi_apic_instance);
a1fdcc0d2   Len Brown   ACPI: Add support...
778

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
779
780
  	return 0;
  }
a1fdcc0d2   Len Brown   ACPI: Add support...
781
782
  
  early_param("acpi_apic_instance", acpi_parse_apic_instance);
4fc0a7e88   Lv Zheng   ACPI: Fix x86 reg...
783
784
785
786
787
788
789
790
791
  
  static int __init acpi_force_table_verification_setup(char *s)
  {
  	acpi_verify_table_checksum = true;
  
  	return 0;
  }
  
  early_param("acpi_force_table_verification", acpi_force_table_verification_setup);
b2ca5dae3   Colin Ian King   ACPI: Add acpi_fo...
792
793
794
795
796
797
798
799
800
801
802
  
  static int __init acpi_force_32bit_fadt_addr(char *s)
  {
  	pr_info("Forcing 32 Bit FADT addresses
  ");
  	acpi_gbl_use32_bit_fadt_addresses = TRUE;
  
  	return 0;
  }
  
  early_param("acpi_force_32bit_fadt_addr", acpi_force_32bit_fadt_addr);