aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/tables/tbutils.c
diff options
context:
space:
mode:
authorBob Moore <robert.moore@intel.com>2007-02-02 11:48:19 -0500
committerLen Brown <len.brown@intel.com>2007-02-02 21:14:21 -0500
commitc5fc42ac4d4d6d3e3f619290b86890cb3725d2f8 (patch)
tree884123d40fe2abf621ec436e55b2d79efa5b474a /drivers/acpi/tables/tbutils.c
parentf3d2e7865c816258c699ff965768e46b50d536d3 (diff)
ACPICA: misc fixes for new Table Manager:
Signed-off-by: Alexey Starikovskiy <alexey.y.starikovskiy@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/tables/tbutils.c')
-rw-r--r--drivers/acpi/tables/tbutils.c544
1 files changed, 343 insertions, 201 deletions
diff --git a/drivers/acpi/tables/tbutils.c b/drivers/acpi/tables/tbutils.c
index 3620ac5f8681..2f4ab751d778 100644
--- a/drivers/acpi/tables/tbutils.c
+++ b/drivers/acpi/tables/tbutils.c
@@ -48,11 +48,52 @@
48ACPI_MODULE_NAME("tbutils") 48ACPI_MODULE_NAME("tbutils")
49 49
50/* Local prototypes */ 50/* Local prototypes */
51static void acpi_tb_parse_fadt(struct acpi_table_fadt *fadt, u8 flags); 51static void acpi_tb_parse_fadt(acpi_native_uint table_index, u8 flags);
52
53static void acpi_tb_convert_fadt(void);
54
55static void
56acpi_tb_install_table(acpi_physical_address address,
57 u8 flags, char *signature, acpi_native_uint table_index);
52 58
53static void inline 59static void inline
54acpi_tb_init_generic_address(struct acpi_generic_address *new_gas_struct, 60acpi_tb_init_generic_address(struct acpi_generic_address *new_gas_struct,
55 u8 bit_width, acpi_physical_address address); 61 u8 bit_width, u64 address);
62
63/* Table used for conversion of FADT to common format */
64
65typedef struct acpi_fadt_conversion {
66 u8 target;
67 u8 source;
68 u8 length;
69
70} acpi_fadt_conversion;
71
72static struct acpi_fadt_conversion fadt_conversion_table[] = {
73 {ACPI_FADT_OFFSET(xpm1a_event_block),
74 ACPI_FADT_OFFSET(pm1a_event_block),
75 ACPI_FADT_OFFSET(pm1_event_length)},
76 {ACPI_FADT_OFFSET(xpm1b_event_block),
77 ACPI_FADT_OFFSET(pm1b_event_block),
78 ACPI_FADT_OFFSET(pm1_event_length)},
79 {ACPI_FADT_OFFSET(xpm1a_control_block),
80 ACPI_FADT_OFFSET(pm1a_control_block),
81 ACPI_FADT_OFFSET(pm1_control_length)},
82 {ACPI_FADT_OFFSET(xpm1b_control_block),
83 ACPI_FADT_OFFSET(pm1b_control_block),
84 ACPI_FADT_OFFSET(pm1_control_length)},
85 {ACPI_FADT_OFFSET(xpm2_control_block),
86 ACPI_FADT_OFFSET(pm2_control_block),
87 ACPI_FADT_OFFSET(pm2_control_length)},
88 {ACPI_FADT_OFFSET(xpm_timer_block), ACPI_FADT_OFFSET(pm_timer_block),
89 ACPI_FADT_OFFSET(pm_timer_length)},
90 {ACPI_FADT_OFFSET(xgpe0_block), ACPI_FADT_OFFSET(gpe0_block),
91 ACPI_FADT_OFFSET(gpe0_block_length)},
92 {ACPI_FADT_OFFSET(xgpe1_block), ACPI_FADT_OFFSET(gpe1_block),
93 ACPI_FADT_OFFSET(gpe1_block_length)}
94};
95
96#define ACPI_FADT_CONVERSION_ENTRIES (sizeof (fadt_conversion_table) / sizeof (struct acpi_fadt_conversion))
56 97
57/******************************************************************************* 98/*******************************************************************************
58 * 99 *
@@ -63,7 +104,7 @@ acpi_tb_init_generic_address(struct acpi_generic_address *new_gas_struct,
63 * 104 *
64 * RETURN: None 105 * RETURN: None
65 * 106 *
66 * DESCRIPTION: Print an ACPI table header 107 * DESCRIPTION: Print an ACPI table header. Special cases for FACS and RSDP.
67 * 108 *
68 ******************************************************************************/ 109 ******************************************************************************/
69 110
@@ -72,12 +113,32 @@ acpi_tb_print_table_header(acpi_physical_address address,
72 struct acpi_table_header *header) 113 struct acpi_table_header *header)
73{ 114{
74 115
75 ACPI_INFO((AE_INFO, 116 if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_FACS)) {
76 "%4.4s @ 0x%p Length 0x%04X (v%3.3d %6.6s %8.8s 0x%08X %4.4s 0x%08X)", 117
77 header->signature, ACPI_CAST_PTR(void, address), 118 /* FACS only has signature and length fields of common table header */
78 header->length, header->revision, header->oem_id, 119
79 header->oem_table_id, header->oem_revision, 120 ACPI_INFO((AE_INFO, "%4.4s @ 0x%p/0x%04X",
80 header->asl_compiler_id, header->asl_compiler_revision)); 121 header->signature, ACPI_CAST_PTR(void, address),
122 header->length));
123 } else if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_RSDP)) {
124
125 /* RSDP has no common fields */
126
127 ACPI_INFO((AE_INFO, "RSDP @ 0x%p/0x%04X (v%3.3d %6.6s)",
128 ACPI_CAST_PTR(void, address),
129 (((struct acpi_table_rsdp *)header)->revision > 0) ?
130 ((struct acpi_table_rsdp *)header)->length : 20,
131 ((struct acpi_table_rsdp *)header)->revision,
132 ((struct acpi_table_rsdp *)header)->oem_id));
133 } else {
134 ACPI_INFO((AE_INFO,
135 "%4.4s @ 0x%p/0x%04X (v%3.3d %6.6s %8.8s 0x%08X %4.4s 0x%08X)",
136 header->signature, ACPI_CAST_PTR(void, address),
137 header->length, header->revision, header->oem_id,
138 header->oem_table_id, header->oem_revision,
139 header->asl_compiler_id,
140 header->asl_compiler_revision));
141 }
81} 142}
82 143
83/******************************************************************************* 144/*******************************************************************************
@@ -96,7 +157,7 @@ acpi_tb_print_table_header(acpi_physical_address address,
96 157
97static void inline 158static void inline
98acpi_tb_init_generic_address(struct acpi_generic_address *new_gas_struct, 159acpi_tb_init_generic_address(struct acpi_generic_address *new_gas_struct,
99 u8 bit_width, acpi_physical_address address) 160 u8 bit_width, u64 address)
100{ 161{
101 162
102 ACPI_STORE_ADDRESS(new_gas_struct->address, address); 163 ACPI_STORE_ADDRESS(new_gas_struct->address, address);
@@ -108,6 +169,45 @@ acpi_tb_init_generic_address(struct acpi_generic_address *new_gas_struct,
108 169
109/******************************************************************************* 170/*******************************************************************************
110 * 171 *
172 * FUNCTION: acpi_tb_validate_checksum
173 *
174 * PARAMETERS: Table - ACPI table to verify
175 * Length - Length of entire table
176 *
177 * RETURN: Status
178 *
179 * DESCRIPTION: Verifies that the table checksums to zero. Optionally returns
180 * exception on bad checksum.
181 *
182 ******************************************************************************/
183
184acpi_status acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length)
185{
186 u8 checksum;
187
188 /* Compute the checksum on the table */
189
190 checksum = acpi_tb_checksum(ACPI_CAST_PTR(u8, table), length);
191
192 /* Checksum ok? (should be zero) */
193
194 if (checksum) {
195 ACPI_WARNING((AE_INFO,
196 "Incorrect checksum in table [%4.4s] - %2.2X, should be %2.2X",
197 table->signature, table->checksum,
198 (u8) (table->checksum - checksum)));
199
200#if (ACPI_CHECKSUM_ABORT)
201
202 return (AE_BAD_CHECKSUM);
203#endif
204 }
205
206 return (AE_OK);
207}
208
209/*******************************************************************************
210 *
111 * FUNCTION: acpi_tb_checksum 211 * FUNCTION: acpi_tb_checksum
112 * 212 *
113 * PARAMETERS: Buffer - Pointer to memory region to be checked 213 * PARAMETERS: Buffer - Pointer to memory region to be checked
@@ -135,24 +235,38 @@ u8 acpi_tb_checksum(u8 * buffer, acpi_native_uint length)
135 * 235 *
136 * FUNCTION: acpi_tb_convert_fadt 236 * FUNCTION: acpi_tb_convert_fadt
137 * 237 *
138 * PARAMETERS: Fadt - FADT table to be converted 238 * PARAMETERS: None, uses acpi_gbl_FADT
139 * 239 *
140 * RETURN: None 240 * RETURN: None
141 * 241 *
142 * DESCRIPTION: Converts a BIOS supplied ACPI 1.0 FADT to a local 242 * DESCRIPTION: Converts all versions of the FADT to a common internal format.
143 * ACPI 2.0 FADT. If the BIOS supplied a 2.0 FADT then it is simply 243 *
144 * copied to the local FADT. The ACPI CA software uses this 244 * NOTE: acpi_gbl_FADT must be of size (struct acpi_table_fadt), and must contain
145 * local FADT. Thus a significant amount of special #ifdef 245 * a copy of the actual FADT.
146 * type codeing is saved. 246 *
247 * ACPICA will use the "X" fields of the FADT for all addresses.
248 *
249 * "X" fields are optional extensions to the original V1.0 fields. Even if
250 * they are present in the structure, they can be optionally not used by
251 * setting them to zero. Therefore, we must selectively expand V1.0 fields
252 * if the corresponding X field is zero.
253 *
254 * For ACPI 1.0 FADTs, all address fields are expanded to the corresponding
255 * "X" fields.
256 *
257 * For ACPI 2.0 FADTs, any "X" fields that are NULL are filled in by
258 * expanding the corresponding ACPI 1.0 field.
147 * 259 *
148 ******************************************************************************/ 260 ******************************************************************************/
149 261
150void acpi_tb_convert_fadt(struct acpi_table_fadt *fadt) 262static void acpi_tb_convert_fadt(void)
151{ 263{
264 u8 pm1_register_length;
265 struct acpi_generic_address *target;
266 acpi_native_uint i;
267
268 /* Expand the FACS and DSDT addresses as necessary */
152 269
153 /*
154 * Convert table pointers to 64-bit fields
155 */
156 if (!acpi_gbl_FADT.Xfacs) { 270 if (!acpi_gbl_FADT.Xfacs) {
157 acpi_gbl_FADT.Xfacs = (u64) acpi_gbl_FADT.facs; 271 acpi_gbl_FADT.Xfacs = (u64) acpi_gbl_FADT.facs;
158 } 272 }
@@ -162,62 +276,49 @@ void acpi_tb_convert_fadt(struct acpi_table_fadt *fadt)
162 } 276 }
163 277
164 /* 278 /*
165 * Convert the V1.0 block addresses to V2.0 GAS structures 279 * Expand the V1.0 addresses to the "X" generic address structs,
280 * as necessary.
166 */ 281 */
167 acpi_tb_init_generic_address(&acpi_gbl_FADT.xpm1a_event_block, 282 for (i = 0; i < ACPI_FADT_CONVERSION_ENTRIES; i++) {
168 acpi_gbl_FADT.pm1_event_length, 283 target =
169 (acpi_physical_address) acpi_gbl_FADT. 284 ACPI_ADD_PTR(struct acpi_generic_address, &acpi_gbl_FADT,
170 pm1a_event_block); 285 fadt_conversion_table[i].target);
171 acpi_tb_init_generic_address(&acpi_gbl_FADT.xpm1b_event_block, 286
172 acpi_gbl_FADT.pm1_event_length, 287 if (!target->address) {
173 (acpi_physical_address) acpi_gbl_FADT. 288 acpi_tb_init_generic_address(target,
174 pm1b_event_block); 289 *ACPI_ADD_PTR(u8,
175 acpi_tb_init_generic_address(&acpi_gbl_FADT.xpm1a_control_block, 290 &acpi_gbl_FADT,
176 acpi_gbl_FADT.pm1_control_length, 291 fadt_conversion_table
177 (acpi_physical_address) acpi_gbl_FADT. 292 [i].length),
178 pm1a_control_block); 293 *ACPI_ADD_PTR(u64,
179 acpi_tb_init_generic_address(&acpi_gbl_FADT.xpm1b_control_block, 294 &acpi_gbl_FADT,
180 acpi_gbl_FADT.pm1_control_length, 295 fadt_conversion_table
181 (acpi_physical_address) acpi_gbl_FADT. 296 [i].source));
182 pm1b_control_block); 297 }
183 acpi_tb_init_generic_address(&acpi_gbl_FADT.xpm2_control_block, 298 }
184 acpi_gbl_FADT.pm2_control_length,
185 (acpi_physical_address) acpi_gbl_FADT.
186 pm2_control_block);
187 acpi_tb_init_generic_address(&acpi_gbl_FADT.xpm_timer_block,
188 acpi_gbl_FADT.pm_timer_length,
189 (acpi_physical_address) acpi_gbl_FADT.
190 pm_timer_block);
191 acpi_tb_init_generic_address(&acpi_gbl_FADT.xgpe0_block, 0,
192 (acpi_physical_address) acpi_gbl_FADT.
193 gpe0_block);
194 acpi_tb_init_generic_address(&acpi_gbl_FADT.xgpe1_block, 0,
195 (acpi_physical_address) acpi_gbl_FADT.
196 gpe1_block);
197 299
198 /* 300 /*
199 * Create separate GAS structs for the PM1 Enable registers 301 * Calculate separate GAS structs for the PM1 Enable registers.
302 * These addresses do not appear (directly) in the FADT, so it is
303 * useful to calculate them once, here.
200 */ 304 */
305 pm1_register_length = (u8) ACPI_DIV_2(acpi_gbl_FADT.pm1_event_length);
306
307 /* PM1A is required */
308
201 acpi_tb_init_generic_address(&acpi_gbl_xpm1a_enable, 309 acpi_tb_init_generic_address(&acpi_gbl_xpm1a_enable,
202 (u8) ACPI_DIV_2(acpi_gbl_FADT. 310 pm1_register_length,
203 pm1_event_length), 311 (u64) (acpi_gbl_FADT.xpm1a_event_block.
204 (acpi_physical_address) 312 address + pm1_register_length));
205 (acpi_gbl_FADT.xpm1a_event_block.address + 313
206 ACPI_DIV_2(acpi_gbl_FADT. 314 /* PM1B is optional; leave null if not present */
207 pm1_event_length)));
208 315
209 /*
210 * PM1B is optional; leave null if not present
211 */
212 if (acpi_gbl_FADT.xpm1b_event_block.address) { 316 if (acpi_gbl_FADT.xpm1b_event_block.address) {
213 acpi_tb_init_generic_address(&acpi_gbl_xpm1b_enable, 317 acpi_tb_init_generic_address(&acpi_gbl_xpm1b_enable,
214 (u8) ACPI_DIV_2(acpi_gbl_FADT. 318 pm1_register_length,
215 pm1_event_length), 319 (u64) (acpi_gbl_FADT.
216 (acpi_physical_address) 320 xpm1b_event_block.address +
217 (acpi_gbl_FADT.xpm1b_event_block. 321 pm1_register_length));
218 address +
219 ACPI_DIV_2(acpi_gbl_FADT.
220 pm1_event_length)));
221 } 322 }
222 323
223 /* Global FADT is the new common V2.0 FADT */ 324 /* Global FADT is the new common V2.0 FADT */
@@ -227,84 +328,132 @@ void acpi_tb_convert_fadt(struct acpi_table_fadt *fadt)
227 328
228/******************************************************************************* 329/*******************************************************************************
229 * 330 *
230 * FUNCTION: acpi_tb_parse_fadt 331 * FUNCTION: acpi_tb_install_table
231 * 332 *
232 * PARAMETERS: Fadt - Pointer to FADT table 333 * PARAMETERS: Address - Physical address of DSDT or FACS
233 * Flags - Flags 334 * Flags - Flags
335 * Signature - Table signature, NULL if no need to
336 * match
337 * table_index - Index into root table array
234 * 338 *
235 * RETURN: none 339 * RETURN: None
236 * 340 *
237 * DESCRIPTION: This function is called to initialise the FADT, DSDT and FACS 341 * DESCRIPTION: Install an ACPI table into the global data structure.
238 * tables (FADT contains the addresses of the DSDT and FACS)
239 * 342 *
240 ******************************************************************************/ 343 ******************************************************************************/
241 344
242static void acpi_tb_parse_fadt(struct acpi_table_fadt *fadt, u8 flags) 345static void
346acpi_tb_install_table(acpi_physical_address address,
347 u8 flags, char *signature, acpi_native_uint table_index)
243{ 348{
244 acpi_physical_address dsdt_address =
245 (acpi_physical_address) fadt->Xdsdt;
246 acpi_physical_address facs_address =
247 (acpi_physical_address) fadt->Xfacs;
248 struct acpi_table_header *table; 349 struct acpi_table_header *table;
249 350
250 if (!dsdt_address) { 351 if (!address) {
251 goto no_dsdt; 352 ACPI_ERROR((AE_INFO,
353 "Null physical address for ACPI table [%s]",
354 signature));
355 return;
252 } 356 }
253 357
254 table = 358 /* Map just the table header */
255 acpi_os_map_memory(dsdt_address, sizeof(struct acpi_table_header)); 359
360 table = acpi_os_map_memory(address, sizeof(struct acpi_table_header));
256 if (!table) { 361 if (!table) {
257 goto no_dsdt; 362 return;
363 }
364
365 /* If a particular signature is expected, signature must match */
366
367 if (signature && !ACPI_COMPARE_NAME(table->signature, signature)) {
368 ACPI_ERROR((AE_INFO,
369 "Invalid signature 0x%X for ACPI table [%s]",
370 *ACPI_CAST_PTR(u32, table->signature), signature));
371 goto unmap_and_exit;
258 } 372 }
259 373
260 /* Initialize the DSDT table */ 374 /* Initialize the table entry */
375
376 acpi_gbl_root_table_list.tables[table_index].address = address;
377 acpi_gbl_root_table_list.tables[table_index].length = table->length;
378 acpi_gbl_root_table_list.tables[table_index].flags = flags;
261 379
262 ACPI_MOVE_32_TO_32(& 380 ACPI_MOVE_32_TO_32(&
263 (acpi_gbl_root_table_list. 381 (acpi_gbl_root_table_list.tables[table_index].
264 tables[ACPI_TABLE_INDEX_DSDT].signature), 382 signature), table->signature);
265 ACPI_SIG_DSDT);
266 383
267 acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].address = 384 acpi_tb_print_table_header(address, table);
268 dsdt_address;
269 acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].length =
270 table->length;
271 acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].flags = flags;
272 385
273 acpi_tb_print_table_header(dsdt_address, table); 386 if (table_index == ACPI_TABLE_INDEX_DSDT) {
274 387
275 /* Global integer width is based upon revision of the DSDT */ 388 /* Global integer width is based upon revision of the DSDT */
276 389
277 acpi_ut_set_integer_width(table->revision); 390 acpi_ut_set_integer_width(table->revision);
391 }
392
393 unmap_and_exit:
278 acpi_os_unmap_memory(table, sizeof(struct acpi_table_header)); 394 acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
395}
279 396
280 no_dsdt: 397/*******************************************************************************
281 if (!facs_address) { 398 *
282 return; 399 * FUNCTION: acpi_tb_parse_fadt
283 } 400 *
401 * PARAMETERS: table_index - Index for the FADT
402 * Flags - Flags
403 *
404 * RETURN: None
405 *
406 * DESCRIPTION: Initialize the FADT, DSDT and FACS tables
407 * (FADT contains the addresses of the DSDT and FACS)
408 *
409 ******************************************************************************/
410
411static void acpi_tb_parse_fadt(acpi_native_uint table_index, u8 flags)
412{
413 u32 length;
414 struct acpi_table_header *table;
415
416 /*
417 * Special case for the FADT because of multiple versions and the fact
418 * that it contains pointers to both the DSDT and FACS tables.
419 *
420 * Get a local copy of the FADT and convert it to a common format
421 * Map entire FADT, assumed to be smaller than one page.
422 */
423 length = acpi_gbl_root_table_list.tables[table_index].length;
284 424
285 table = 425 table =
286 acpi_os_map_memory(facs_address, sizeof(struct acpi_table_header)); 426 acpi_os_map_memory(acpi_gbl_root_table_list.tables[table_index].
427 address, length);
287 if (!table) { 428 if (!table) {
288 return; 429 return;
289 } 430 }
290 431
291 /* Initialize the FACS table */ 432 /*
433 * Validate the FADT checksum before we copy the table. Ignore
434 * checksum error as we want to try to get the DSDT and FACS.
435 */
436 (void)acpi_tb_verify_checksum(table, length);
292 437
293 ACPI_MOVE_32_TO_32(& 438 /* Copy the entire FADT locally */
294 (acpi_gbl_root_table_list.
295 tables[ACPI_TABLE_INDEX_FACS].signature),
296 ACPI_SIG_FACS);
297 439
298 acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_FACS].address = 440 ACPI_MEMSET(&acpi_gbl_FADT, sizeof(struct acpi_table_fadt), 0);
299 facs_address;
300 acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_FACS].length =
301 table->length;
302 acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_FACS].flags = flags;
303 441
304 ACPI_INFO((AE_INFO, "%4.4s @ 0x%p", 442 ACPI_MEMCPY(&acpi_gbl_FADT, table,
305 table->signature, ACPI_CAST_PTR(void, facs_address))); 443 ACPI_MIN(length, sizeof(struct acpi_table_fadt)));
444 acpi_os_unmap_memory(table, length);
306 445
307 acpi_os_unmap_memory(table, sizeof(struct acpi_table_header)); 446 /* Convert local FADT to the common internal format */
447
448 acpi_tb_convert_fadt();
449
450 /* Extract the DSDT and FACS tables from the FADT */
451
452 acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xdsdt,
453 flags, ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT);
454
455 acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xfacs,
456 flags, ACPI_SIG_FACS, ACPI_TABLE_INDEX_FACS);
308} 457}
309 458
310/******************************************************************************* 459/*******************************************************************************
@@ -325,20 +474,33 @@ static void acpi_tb_parse_fadt(struct acpi_table_fadt *fadt, u8 flags)
325 * 474 *
326 ******************************************************************************/ 475 ******************************************************************************/
327 476
328acpi_status acpi_tb_parse_root_table(struct acpi_table_rsdp *rsdp, u8 flags) 477acpi_status
478acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags)
329{ 479{
480 struct acpi_table_rsdp *rsdp;
481 acpi_native_uint table_entry_size;
482 acpi_native_uint i;
483 u32 table_count;
330 struct acpi_table_header *table; 484 struct acpi_table_header *table;
331 acpi_physical_address address; 485 acpi_physical_address address;
332 u32 length; 486 u32 length;
333 u8 *table_entry; 487 u8 *table_entry;
334 acpi_native_uint i;
335 acpi_native_uint pointer_size;
336 u32 table_count;
337 u8 checksum;
338 acpi_status status; 488 acpi_status status;
339 489
340 ACPI_FUNCTION_TRACE(tb_parse_root_table); 490 ACPI_FUNCTION_TRACE(tb_parse_root_table);
341 491
492 /*
493 * Map the entire RSDP and extract the address of the RSDT or XSDT
494 */
495 rsdp = acpi_os_map_memory(rsdp_address, sizeof(struct acpi_table_rsdp));
496 if (!rsdp) {
497 return_ACPI_STATUS(AE_NO_MEMORY);
498 }
499
500 acpi_tb_print_table_header(rsdp_address,
501 ACPI_CAST_PTR(struct acpi_table_header,
502 rsdp));
503
342 /* Differentiate between RSDT and XSDT root tables */ 504 /* Differentiate between RSDT and XSDT root tables */
343 505
344 if (rsdp->revision > 1 && rsdp->xsdt_physical_address) { 506 if (rsdp->revision > 1 && rsdp->xsdt_physical_address) {
@@ -347,22 +509,30 @@ acpi_status acpi_tb_parse_root_table(struct acpi_table_rsdp *rsdp, u8 flags)
347 * XSDT if the revision is > 1 and the XSDT pointer is present, as per 509 * XSDT if the revision is > 1 and the XSDT pointer is present, as per
348 * the ACPI specification. 510 * the ACPI specification.
349 */ 511 */
350 address = (acpi_native_uint) rsdp->xsdt_physical_address; 512 address = (acpi_physical_address) rsdp->xsdt_physical_address;
351 pointer_size = sizeof(u64); 513 table_entry_size = sizeof(u64);
352 } else { 514 } else {
353 /* Root table is an RSDT (32-bit physical addresses) */ 515 /* Root table is an RSDT (32-bit physical addresses) */
354 516
355 address = (acpi_native_uint) rsdp->rsdt_physical_address; 517 address = (acpi_physical_address) rsdp->rsdt_physical_address;
356 pointer_size = sizeof(u32); 518 table_entry_size = sizeof(u32);
357 } 519 }
358 520
359 /* Map the table header to get the full table length */ 521 /*
522 * It is not possible to map more than one entry in some environments,
523 * so unmap the RSDP here before mapping other tables
524 */
525 acpi_os_unmap_memory(rsdp, sizeof(struct acpi_table_rsdp));
526
527 /* Map the RSDT/XSDT table header to get the full table length */
360 528
361 table = acpi_os_map_memory(address, sizeof(struct acpi_table_header)); 529 table = acpi_os_map_memory(address, sizeof(struct acpi_table_header));
362 if (!table) { 530 if (!table) {
363 return (AE_NO_MEMORY); 531 return_ACPI_STATUS(AE_NO_MEMORY);
364 } 532 }
365 533
534 acpi_tb_print_table_header(address, table);
535
366 /* Get the length of the full table, verify length and map entire table */ 536 /* Get the length of the full table, verify length and map entire table */
367 537
368 length = table->length; 538 length = table->length;
@@ -371,48 +541,45 @@ acpi_status acpi_tb_parse_root_table(struct acpi_table_rsdp *rsdp, u8 flags)
371 if (length < sizeof(struct acpi_table_header)) { 541 if (length < sizeof(struct acpi_table_header)) {
372 ACPI_ERROR((AE_INFO, "Invalid length 0x%X in RSDT/XSDT", 542 ACPI_ERROR((AE_INFO, "Invalid length 0x%X in RSDT/XSDT",
373 length)); 543 length));
374 return (AE_INVALID_TABLE_LENGTH); 544 return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
375 } 545 }
376 546
377 table = acpi_os_map_memory(address, length); 547 table = acpi_os_map_memory(address, length);
378 if (!table) { 548 if (!table) {
379 return (AE_NO_MEMORY); 549 return_ACPI_STATUS(AE_NO_MEMORY);
380 } 550 }
381 551
382 /* Validate the root table checksum */ 552 /* Validate the root table checksum */
383 553
384 checksum = acpi_tb_checksum(ACPI_CAST_PTR(u8, table), length); 554 status = acpi_tb_verify_checksum(table, length);
385#if (ACPI_CHECKSUM_ABORT) 555 if (ACPI_FAILURE(status)) {
386
387 if (checksum) {
388 acpi_os_unmap_memory(table, length); 556 acpi_os_unmap_memory(table, length);
389 return (AE_BAD_CHECKSUM); 557 return_ACPI_STATUS(status);
390 } 558 }
391#endif
392
393 acpi_tb_print_table_header(address, table);
394 559
395 /* Calculate the number of tables described in the root table */ 560 /* Calculate the number of tables described in the root table */
396 561
397 table_count = 562 table_count =
398 (table->length - sizeof(struct acpi_table_header)) / pointer_size; 563 (table->length -
399 564 sizeof(struct acpi_table_header)) / table_entry_size;
400 /* Setup loop */
401 565
566 /*
567 * First two entries in the table array are reserved for the DSDT and FACS,
568 * which are not actually present in the RSDT/XSDT - they come from the FADT
569 */
402 table_entry = 570 table_entry =
403 ACPI_CAST_PTR(u8, table) + sizeof(struct acpi_table_header); 571 ACPI_CAST_PTR(u8, table) + sizeof(struct acpi_table_header);
404 acpi_gbl_root_table_list.count = 2; 572 acpi_gbl_root_table_list.count = 2;
405 573
406 /* 574 /*
407 * Initialize the ACPI table entries 575 * Initialize the root table array from the RSDT/XSDT
408 * First two entries in the table array are reserved for the DSDT and FACS
409 */ 576 */
410 for (i = 0; i < table_count; ++i, table_entry += pointer_size) { 577 for (i = 0; i < table_count; i++) {
411
412 /* Ensure there is room for another table entry */
413
414 if (acpi_gbl_root_table_list.count >= 578 if (acpi_gbl_root_table_list.count >=
415 acpi_gbl_root_table_list.size) { 579 acpi_gbl_root_table_list.size) {
580
581 /* There is no more room in the root table array, attempt resize */
582
416 status = acpi_tb_resize_root_table_list(); 583 status = acpi_tb_resize_root_table_list();
417 if (ACPI_FAILURE(status)) { 584 if (ACPI_FAILURE(status)) {
418 ACPI_WARNING((AE_INFO, 585 ACPI_WARNING((AE_INFO,
@@ -425,20 +592,34 @@ acpi_status acpi_tb_parse_root_table(struct acpi_table_rsdp *rsdp, u8 flags)
425 } 592 }
426 } 593 }
427 594
428 /* Get the physical address (32-bit for RSDT, 64-bit for XSDT) */ 595 /*
429 596 * Get the table physical address (32-bit for RSDT, 64-bit for XSDT)
430 if (pointer_size == sizeof(u32)) { 597 */
598 if ((table_entry_size == sizeof(u32)) ||
599 (sizeof(acpi_physical_address) == sizeof(u32))) {
600 /*
601 * 32-bit platform, RSDT: Move 32-bit to 32-bit
602 * 32-bit platform, XSDT: Truncate 64-bit to 32-bit
603 * 64-bit platform, RSDT: Expand 32-bit to 64-bit
604 *
605 * Note: Addresses are 32-bit aligned in both RSDT and XSDT
606 */
431 acpi_gbl_root_table_list. 607 acpi_gbl_root_table_list.
432 tables[acpi_gbl_root_table_list.count].address = 608 tables[acpi_gbl_root_table_list.count].address =
433 (acpi_physical_address) (*ACPI_CAST_PTR 609 (acpi_physical_address) (*ACPI_CAST_PTR
434 (u32, table_entry)); 610 (u32, table_entry));
435 } else { 611 } else {
436 acpi_gbl_root_table_list. 612 /*
437 tables[acpi_gbl_root_table_list.count].address = 613 * 64-bit platform, XSDT: Move 64-bit to 64-bit
438 (acpi_physical_address) (*ACPI_CAST_PTR 614 *
439 (u64, table_entry)); 615 * Note: 64-bit addresses are only 32-bit aligned in the XSDT
616 */
617 ACPI_MOVE_64_TO_64(&acpi_gbl_root_table_list.
618 tables[acpi_gbl_root_table_list.
619 count].address, table_entry);
440 } 620 }
441 621
622 table_entry += table_entry_size;
442 acpi_gbl_root_table_list.count++; 623 acpi_gbl_root_table_list.count++;
443 } 624 }
444 625
@@ -448,59 +629,20 @@ acpi_status acpi_tb_parse_root_table(struct acpi_table_rsdp *rsdp, u8 flags)
448 */ 629 */
449 acpi_os_unmap_memory(table, length); 630 acpi_os_unmap_memory(table, length);
450 631
451 /* Initialize all tables other than the DSDT and FACS */ 632 /*
452 633 * Complete the initialization of the root table array by examining
634 * the header of each table
635 */
453 for (i = 2; i < acpi_gbl_root_table_list.count; i++) { 636 for (i = 2; i < acpi_gbl_root_table_list.count; i++) {
454 address = acpi_gbl_root_table_list.tables[i].address; 637 acpi_tb_install_table(acpi_gbl_root_table_list.tables[i].
455 length = sizeof(struct acpi_table_header); 638 address, flags, NULL, i);
456
457 table = acpi_os_map_memory(address, length);
458 if (!table) {
459 continue;
460 }
461
462 acpi_gbl_root_table_list.tables[i].length = table->length;
463 acpi_gbl_root_table_list.tables[i].flags = flags;
464
465 ACPI_MOVE_32_TO_32(&
466 (acpi_gbl_root_table_list.tables[i].
467 signature), table->signature);
468
469 acpi_tb_print_table_header(address, table);
470
471 /*
472 * Special case for the FADT because of multiple versions -
473 * get a local copy and convert to common format
474 */
475 if (ACPI_COMPARE_NAME(table->signature, ACPI_SIG_FADT)) {
476 acpi_os_unmap_memory(table, length);
477 length = table->length;
478
479 table = acpi_os_map_memory(address, length);
480 if (!table) {
481 continue;
482 }
483
484 /* Copy the entire FADT locally */
485
486 ACPI_MEMCPY(&acpi_gbl_FADT, table,
487 ACPI_MIN(table->length,
488 sizeof(struct acpi_table_fadt)));
489 639
490 /* Small table means old revision, convert to new */ 640 /* Special case for FADT - get the DSDT and FACS */
491 641
492 if (table->length < sizeof(struct acpi_table_fadt)) { 642 if (ACPI_COMPARE_NAME
493 acpi_tb_convert_fadt(ACPI_CAST_PTR 643 (&acpi_gbl_root_table_list.tables[i].signature,
494 (struct acpi_table_fadt, 644 ACPI_SIG_FADT)) {
495 table)); 645 acpi_tb_parse_fadt(i, flags);
496 }
497
498 /* Unmap original FADT */
499
500 acpi_os_unmap_memory(table, length);
501 acpi_tb_parse_fadt(&acpi_gbl_FADT, flags);
502 } else {
503 acpi_os_unmap_memory(table, length);
504 } 646 }
505 } 647 }
506 648