Blame view

drivers/acpi/tables.c 20.8 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
  acpi_table_parse_entries_array(char *id,
f08bb472b   Ashwin Chaugule   ACPI / table: Add...
309
  			 unsigned long table_size,
9b3fedde2   Lukasz Anaczkowski   ACPI / tables: Ad...
310
  			 struct acpi_subtable_proc *proc, int proc_num,
f08bb472b   Ashwin Chaugule   ACPI / table: Add...
311
312
313
  			 unsigned int max_entries)
  {
  	struct acpi_table_header *table_header = NULL;
f08bb472b   Ashwin Chaugule   ACPI / table: Add...
314
315
316
317
318
  	int count;
  	u32 instance = 0;
  
  	if (acpi_disabled)
  		return -ENODEV;
9b3fedde2   Lukasz Anaczkowski   ACPI / tables: Ad...
319
  	if (!id)
f08bb472b   Ashwin Chaugule   ACPI / table: Add...
320
321
322
323
  		return -EINVAL;
  
  	if (!strncmp(id, ACPI_SIG_MADT, 4))
  		instance = acpi_apic_instance;
6b11d1d67   Lv Zheng   ACPI / osl: Remov...
324
  	acpi_get_table(id, instance, &table_header);
f08bb472b   Ashwin Chaugule   ACPI / table: Add...
325
326
327
328
329
  	if (!table_header) {
  		pr_warn("%4.4s not present
  ", id);
  		return -ENODEV;
  	}
9b3fedde2   Lukasz Anaczkowski   ACPI / tables: Ad...
330
331
  	count = acpi_parse_entries_array(id, table_size, table_header,
  			proc, proc_num, max_entries);
f08bb472b   Ashwin Chaugule   ACPI / table: Add...
332

6b11d1d67   Lv Zheng   ACPI / osl: Remov...
333
  	acpi_put_table(table_header);
f08bb472b   Ashwin Chaugule   ACPI / table: Add...
334
  	return count;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
335
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
336
  int __init
9b3fedde2   Lukasz Anaczkowski   ACPI / tables: Ad...
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
  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...
353
  acpi_table_parse_madt(enum acpi_madt_type id,
b43e1065c   Lv Zheng   ACPICA: Cleanup t...
354
  		      acpi_tbl_entry_handler handler, unsigned int max_entries)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
355
  {
6eb87fed5   Len Brown   ACPI: acpi_table_...
356
  	return acpi_table_parse_entries(ACPI_SIG_MADT,
4be44fcd3   Len Brown   [ACPI] Lindent al...
357
358
  					    sizeof(struct acpi_table_madt), id,
  					    handler, max_entries);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
359
  }
7f8f97c3c   Len Brown   ACPI: acpi_table_...
360
361
  /**
   * acpi_table_parse - find table with @id, run @handler on it
7f8f97c3c   Len Brown   ACPI: acpi_table_...
362
363
364
365
   * @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...
366
367
368
   * run @handler on it.
   *
   * Return 0 if table found, -errno if not.
7f8f97c3c   Len Brown   ACPI: acpi_table_...
369
   */
b43e1065c   Lv Zheng   ACPICA: Cleanup t...
370
  int __init acpi_table_parse(char *id, acpi_tbl_table_handler handler)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
371
  {
ceb6c4683   Alexey Starikovskiy   ACPICA: Remove du...
372
  	struct acpi_table_header *table = NULL;
a1fdcc0d2   Len Brown   ACPI: Add support...
373

68ca40693   Len Brown   ACPI: delete the ...
374
  	if (acpi_disabled)
e5b8fc6ac   Len Brown   ACPI: check acpi_...
375
  		return -ENODEV;
de2d1a7e9   tangchen   ACPI / tables: Ch...
376
  	if (!id || !handler)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
377
  		return -EINVAL;
a1fdcc0d2   Len Brown   ACPI: Add support...
378
  	if (strncmp(id, ACPI_SIG_MADT, 4) == 0)
6b11d1d67   Lv Zheng   ACPI / osl: Remov...
379
  		acpi_get_table(id, acpi_apic_instance, &table);
a1fdcc0d2   Len Brown   ACPI: Add support...
380
  	else
6b11d1d67   Lv Zheng   ACPI / osl: Remov...
381
  		acpi_get_table(id, 0, &table);
a1fdcc0d2   Len Brown   ACPI: Add support...
382

ceb6c4683   Alexey Starikovskiy   ACPICA: Remove du...
383
384
  	if (table) {
  		handler(table);
6b11d1d67   Lv Zheng   ACPI / osl: Remov...
385
  		acpi_put_table(table);
ceb6c4683   Alexey Starikovskiy   ACPICA: Remove du...
386
  		return 0;
7f8f97c3c   Len Brown   ACPI: acpi_table_...
387
  	} else
95df812db   Hanjun Guo   ACPI / table: Rep...
388
  		return -ENODEV;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
389
  }
a1fdcc0d2   Len Brown   ACPI: Add support...
390
391
392
393
394
395
396
397
  /* 
   * 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;
6b11d1d67   Lv Zheng   ACPI / osl: Remov...
398
  	acpi_get_table(ACPI_SIG_MADT, 2, &table);
a1fdcc0d2   Len Brown   ACPI: Add support...
399
  	if (table) {
730bf5ebb   Hanjun Guo   ACPI / tables: Re...
400
401
402
403
404
405
406
  		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);
6b11d1d67   Lv Zheng   ACPI / osl: Remov...
407
  		acpi_put_table(table);
a1fdcc0d2   Len Brown   ACPI: Add support...
408
409
410
411
412
413
  
  	} else
  		acpi_apic_instance = 0;
  
  	return;
  }
5ae74f2cc   Lv Zheng   ACPI / tables: Mo...
414
415
416
417
418
419
420
  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...
421
  #ifdef CONFIG_ACPI_TABLE_UPGRADE
5ae74f2cc   Lv Zheng   ACPI / tables: Mo...
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
  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...
449
450
451
  #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...
452
453
  
  #define MAP_CHUNK_SIZE   (NR_FIX_BTMAPS << PAGE_SHIFT)
da3d3f98d   Aleksey Makarov   ACPI / tables: ta...
454
  void __init acpi_table_upgrade(void)
5ae74f2cc   Lv Zheng   ACPI / tables: Mo...
455
  {
da3d3f98d   Aleksey Makarov   ACPI / tables: ta...
456
457
  	void *data = (void *)initrd_start;
  	size_t size = initrd_end - initrd_start;
5ae74f2cc   Lv Zheng   ACPI / tables: Mo...
458
459
460
461
462
463
464
465
  	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...
466
  	for (no = 0; no < NR_ACPI_INITRD_TABLES; no++) {
5ae74f2cc   Lv Zheng   ACPI / tables: Mo...
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
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
  		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...
519
  		memblock_find_in_range(0, ACPI_TABLE_UPGRADE_MAX_PHYS,
5ae74f2cc   Lv Zheng   ACPI / tables: Mo...
520
521
522
523
524
525
526
527
528
529
530
531
  				       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".
ab6bc04cf   Ingo Molnar   x86/boot/e820: Cr...
532
  	 * Both memblock_reserve and e820__range_add (via arch_reserve_mem_area)
5ae74f2cc   Lv Zheng   ACPI / tables: Mo...
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
  	 * 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...
557
558
  			dest_p = early_memremap(dest_addr & PAGE_MASK,
  						clen + slop);
5ae74f2cc   Lv Zheng   ACPI / tables: Mo...
559
  			memcpy(dest_p + slop, src_p, clen);
ce0c1fcc7   Aleksey Makarov   ACPI / tables: ta...
560
  			early_memunmap(dest_p, clen + slop);
5ae74f2cc   Lv Zheng   ACPI / tables: Mo...
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
  			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...
594
595
596
  		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...
597
598
599
600
601
  		    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...
602
603
604
605
606
607
608
609
610
  		/*
  		 * 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...
611
612
613
  
  		*length = table_length;
  		*address = acpi_tables_addr + table_offset;
5d8813271   Lv Zheng   ACPI / tables: Co...
614
615
616
617
  		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...
618
  		acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
5ae74f2cc   Lv Zheng   ACPI / tables: Mo...
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
  		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...
650
  		if (ACPI_COMPARE_NAME(table->signature, ACPI_SIG_RSDT) ||
5ae74f2cc   Lv Zheng   ACPI / tables: Mo...
651
652
653
654
  		    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...
655
656
657
658
659
660
661
662
663
  		/*
  		 * 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...
664

5d8813271   Lv Zheng   ACPI / tables: Co...
665
666
667
668
  		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...
669
670
  		acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
  		acpi_install_table(acpi_tables_addr + table_offset, TRUE);
5ae74f2cc   Lv Zheng   ACPI / tables: Mo...
671
672
673
674
675
676
  next_table:
  		table_offset += table_length;
  		table_index++;
  	}
  }
  #else
5ae74f2cc   Lv Zheng   ACPI / tables: Mo...
677
678
679
680
681
682
683
684
685
686
687
688
689
  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...
690
  #endif /* CONFIG_ACPI_TABLE_UPGRADE */
5ae74f2cc   Lv Zheng   ACPI / tables: Mo...
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
  
  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
718
719
720
721
722
  /*
   * acpi_table_init()
   *
   * find RSDP, find and checksum SDT/XSDT.
   * checksum all tables, print SDT/XSDT
5f3b1a8b6   Alexey Starikovskiy   ACPICA: Remove du...
723
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
724
725
   * result: sdt_entry[] is initialized
   */
4be44fcd3   Len Brown   [ACPI] Lindent al...
726
  int __init acpi_table_init(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
727
  {
9e3a9d1ed   Len Brown   ACPI: disable ACP...
728
  	acpi_status status;
4fc0a7e88   Lv Zheng   ACPI: Fix x86 reg...
729
730
731
  	if (acpi_verify_table_checksum) {
  		pr_info("Early table checksum verification enabled
  ");
023e2ee16   Lv Zheng   ACPICA: Tables: C...
732
  		acpi_gbl_enable_table_validation = TRUE;
4fc0a7e88   Lv Zheng   ACPI: Fix x86 reg...
733
734
735
  	} else {
  		pr_info("Early table checksum verification disabled
  ");
023e2ee16   Lv Zheng   ACPICA: Tables: C...
736
  		acpi_gbl_enable_table_validation = FALSE;
4fc0a7e88   Lv Zheng   ACPI: Fix x86 reg...
737
  	}
9e3a9d1ed   Len Brown   ACPI: disable ACP...
738
739
  	status = acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0);
  	if (ACPI_FAILURE(status))
95df812db   Hanjun Guo   ACPI / table: Rep...
740
  		return -EINVAL;
5ae74f2cc   Lv Zheng   ACPI / tables: Mo...
741
  	acpi_table_initrd_scan();
9e3a9d1ed   Len Brown   ACPI: disable ACP...
742

a1fdcc0d2   Len Brown   ACPI: Add support...
743
744
745
746
747
748
  	check_multiple_madt();
  	return 0;
  }
  
  static int __init acpi_parse_apic_instance(char *str)
  {
f0df2d6b5   Cyrill Gorcunov   acpi: add checkin...
749
750
  	if (!str)
  		return -EINVAL;
a1fdcc0d2   Len Brown   ACPI: Add support...
751

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

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

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
758
759
  	return 0;
  }
a1fdcc0d2   Len Brown   ACPI: Add support...
760
761
  
  early_param("acpi_apic_instance", acpi_parse_apic_instance);
4fc0a7e88   Lv Zheng   ACPI: Fix x86 reg...
762
763
764
765
766
767
768
769
770
  
  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...
771
772
773
774
775
776
777
778
779
780
781
  
  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);