File: /usr/src/linux/drivers/acpi/tables/tbconvrt.c
1 /******************************************************************************
2 *
3 * Module Name: tbconvrt - ACPI Table conversion utilities
4 * $Revision: 27 $
5 *
6 *****************************************************************************/
7
8 /*
9 * Copyright (C) 2000, 2001 R. Byron Moore
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
26
27 #include "acpi.h"
28 #include "achware.h"
29 #include "actables.h"
30 #include "actbl.h"
31
32
33 #define _COMPONENT ACPI_TABLES
34 MODULE_NAME ("tbconvrt")
35
36
37 /*******************************************************************************
38 *
39 * FUNCTION: Acpi_tb_get_table_count
40 *
41 * PARAMETERS:
42 *
43 * RETURN:
44 *
45 * DESCRIPTION: Calculate the number of tables
46 *
47 ******************************************************************************/
48
49 u32
50 acpi_tb_get_table_count (
51 RSDP_DESCRIPTOR *RSDP,
52 acpi_table_header *RSDT)
53 {
54 u32 pointer_size;
55
56
57 FUNCTION_ENTRY ();
58
59
60 #ifndef _IA64
61
62 if (RSDP->revision < 2) {
63 pointer_size = sizeof (u32);
64 }
65
66 else
67 #endif
68 {
69 pointer_size = sizeof (UINT64);
70 }
71
72 /*
73 * Determine the number of tables pointed to by the RSDT/XSDT.
74 * This is defined by the ACPI Specification to be the number of
75 * pointers contained within the RSDT/XSDT. The size of the pointers
76 * is architecture-dependent.
77 */
78 return ((RSDT->length - sizeof (acpi_table_header)) / pointer_size);
79 }
80
81
82 /*******************************************************************************
83 *
84 * FUNCTION: Acpi_tb_convert_to_xsdt
85 *
86 * PARAMETERS:
87 *
88 * RETURN:
89 *
90 * DESCRIPTION: Convert an RSDT to an XSDT (internal common format)
91 *
92 ******************************************************************************/
93
94 acpi_status
95 acpi_tb_convert_to_xsdt (
96 acpi_table_desc *table_info,
97 u32 *number_of_tables)
98 {
99 u32 table_size;
100 u32 i;
101 xsdt_descriptor *new_table;
102
103
104 FUNCTION_ENTRY ();
105
106
107 *number_of_tables = acpi_tb_get_table_count (acpi_gbl_RSDP, table_info->pointer);
108
109
110 /* Compute size of the converted XSDT */
111
112 table_size = (*number_of_tables * sizeof (UINT64)) + sizeof (acpi_table_header);
113
114
115 /* Allocate an XSDT */
116
117 new_table = ACPI_MEM_CALLOCATE (table_size);
118 if (!new_table) {
119 return (AE_NO_MEMORY);
120 }
121
122 /* Copy the header and set the length */
123
124 MEMCPY (new_table, table_info->pointer, sizeof (acpi_table_header));
125 new_table->header.length = table_size;
126
127 /* Copy the table pointers */
128
129 for (i = 0; i < *number_of_tables; i++) {
130 if (acpi_gbl_RSDP->revision < 2) {
131 #ifdef _IA64
132 new_table->table_offset_entry[i] =
133 ((RSDT_DESCRIPTOR_REV071 *) table_info->pointer)->table_offset_entry[i];
134 #else
135 ACPI_STORE_ADDRESS (new_table->table_offset_entry[i],
136 ((RSDT_DESCRIPTOR_REV1 *) table_info->pointer)->table_offset_entry[i]);
137 #endif
138 }
139 else {
140 new_table->table_offset_entry[i] =
141 ((xsdt_descriptor *) table_info->pointer)->table_offset_entry[i];
142 }
143 }
144
145
146 /* Delete the original table (either mapped or in a buffer) */
147
148 acpi_tb_delete_single_table (table_info);
149
150
151 /* Point the table descriptor to the new table */
152
153 table_info->pointer = (acpi_table_header *) new_table;
154 table_info->base_pointer = (acpi_table_header *) new_table;
155 table_info->length = table_size;
156 table_info->allocation = ACPI_MEM_ALLOCATED;
157
158 return (AE_OK);
159 }
160
161
162 /*******************************************************************************
163 *
164 * FUNCTION: Acpi_tb_convert_table_fadt
165 *
166 * PARAMETERS:
167 *
168 * RETURN:
169 *
170 * DESCRIPTION:
171 * Converts BIOS supplied 1.0 and 0.71 ACPI FADT to an intermediate
172 * ACPI 2.0 FADT. If the BIOS supplied a 2.0 FADT then it is simply
173 * copied to the intermediate FADT. The ACPI CA software uses this
174 * intermediate FADT. Thus a significant amount of special #ifdef
175 * type codeing is saved. This intermediate FADT will need to be
176 * freed at some point.
177 *
178 ******************************************************************************/
179
180 acpi_status
181 acpi_tb_convert_table_fadt (void)
182 {
183
184 #ifdef _IA64
185 fadt_descriptor_rev071 *FADT71;
186 u8 pm1_address_space;
187 u8 pm2_address_space;
188 u8 pm_timer_address_space;
189 u8 gpe0address_space;
190 u8 gpe1_address_space;
191 #else
192 fadt_descriptor_rev1 *FADT1;
193 #endif
194
195 fadt_descriptor_rev2 *FADT2;
196 acpi_table_desc *table_desc;
197
198
199 FUNCTION_TRACE ("Tb_convert_table_fadt");
200
201
202 /* Acpi_gbl_FADT is valid */
203 /* Allocate and zero the 2.0 buffer */
204
205 FADT2 = ACPI_MEM_CALLOCATE (sizeof (fadt_descriptor_rev2));
206 if (FADT2 == NULL) {
207 return_ACPI_STATUS (AE_NO_MEMORY);
208 }
209
210
211 /* The ACPI FADT revision number is FADT2_REVISION_ID=3 */
212 /* So, if the current table revision is less than 3 it is type 1.0 or 0.71 */
213
214 if (acpi_gbl_FADT->header.revision >= FADT2_REVISION_ID) {
215 /* We have an ACPI 2.0 FADT but we must copy it to our local buffer */
216
217 *FADT2 = *((fadt_descriptor_rev2*) acpi_gbl_FADT);
218
219 }
220
221 else {
222
223 #ifdef _IA64
224 /*
225 * For the 64-bit case only, a revision ID less than V2.0 means the
226 * tables are the 0.71 extensions
227 */
228
229 /* The BIOS stored FADT should agree with Revision 0.71 */
230
231 FADT71 = (fadt_descriptor_rev071 *) acpi_gbl_FADT;
232
233 /* Copy the table header*/
234
235 FADT2->header = FADT71->header;
236
237 /* Copy the common fields */
238
239 FADT2->sci_int = FADT71->sci_int;
240 FADT2->acpi_enable = FADT71->acpi_enable;
241 FADT2->acpi_disable = FADT71->acpi_disable;
242 FADT2->S4_bios_req = FADT71->S4_bios_req;
243 FADT2->plvl2_lat = FADT71->plvl2_lat;
244 FADT2->plvl3_lat = FADT71->plvl3_lat;
245 FADT2->day_alrm = FADT71->day_alrm;
246 FADT2->mon_alrm = FADT71->mon_alrm;
247 FADT2->century = FADT71->century;
248 FADT2->gpe1_base = FADT71->gpe1_base;
249
250 /*
251 * We still use the block length registers even though
252 * the GAS structure should obsolete them. This is because
253 * these registers are byte lengths versus the GAS which
254 * contains a bit width
255 */
256 FADT2->pm1_evt_len = FADT71->pm1_evt_len;
257 FADT2->pm1_cnt_len = FADT71->pm1_cnt_len;
258 FADT2->pm2_cnt_len = FADT71->pm2_cnt_len;
259 FADT2->pm_tm_len = FADT71->pm_tm_len;
260 FADT2->gpe0blk_len = FADT71->gpe0blk_len;
261 FADT2->gpe1_blk_len = FADT71->gpe1_blk_len;
262 FADT2->gpe1_base = FADT71->gpe1_base;
263
264 /* Copy the existing 0.71 flags to 2.0. The other bits are zero.*/
265
266 FADT2->wb_invd = FADT71->flush_cash;
267 FADT2->proc_c1 = FADT71->proc_c1;
268 FADT2->plvl2_up = FADT71->plvl2_up;
269 FADT2->pwr_button = FADT71->pwr_button;
270 FADT2->sleep_button = FADT71->sleep_button;
271 FADT2->fixed_rTC = FADT71->fixed_rTC;
272 FADT2->rtcs4 = FADT71->rtcs4;
273 FADT2->tmr_val_ext = FADT71->tmr_val_ext;
274 FADT2->dock_cap = FADT71->dock_cap;
275
276
277 /* We should not use these next two addresses */
278 /* Since our buffer is pre-zeroed nothing to do for */
279 /* the next three data items in the structure */
280 /* FADT2->Firmware_ctrl = 0; */
281 /* FADT2->Dsdt = 0; */
282
283 /* System Interrupt Model isn't used in ACPI 2.0*/
284 /* FADT2->Reserved1 = 0; */
285
286 /* This field is set by the OEM to convey the preferred */
287 /* power management profile to OSPM. It doesn't have any*/
288 /* 0.71 equivalence. Since we don't know what kind of */
289 /* 64-bit system this is, we will pick unspecified. */
290
291 FADT2->prefer_PM_profile = PM_UNSPECIFIED;
292
293
294 /* Port address of SMI command port */
295 /* We shouldn't use this port because IA64 doesn't */
296 /* have or use SMI. It has PMI. */
297
298 FADT2->smi_cmd = (u32)(FADT71->smi_cmd & 0xFFFFFFFF);
299
300
301 /* processor performance state control*/
302 /* The value OSPM writes to the SMI_CMD register to assume */
303 /* processor performance state control responsibility. */
304 /* There isn't any equivalence in 0.71 */
305 /* Again this should be meaningless for IA64 */
306 /* FADT2->Pstate_cnt = 0; */
307
308 /* The 32-bit Power management and GPE registers are */
309 /* not valid in IA-64 and we are not going to use them */
310 /* so leaving them pre-zeroed. */
311
312 /* Support for the _CST object and C States change notification.*/
313 /* This data item hasn't any 0.71 equivalence so leaving it zero.*/
314 /* FADT2->Cst_cnt = 0; */
315
316 /* number of flush strides that need to be read */
317 /* No 0.71 equivalence. Leave pre-zeroed. */
318 /* FADT2->Flush_size = 0; */
319
320 /* Processor's memory cache line width, in bytes */
321 /* No 0.71 equivalence. Leave pre-zeroed. */
322 /* FADT2->Flush_stride = 0; */
323
324 /* Processor's duty cycle index in processor's P_CNT reg*/
325 /* No 0.71 equivalence. Leave pre-zeroed. */
326 /* FADT2->Duty_offset = 0; */
327
328 /* Processor's duty cycle value bit width in P_CNT register.*/
329 /* No 0.71 equivalence. Leave pre-zeroed. */
330 /* FADT2->Duty_width = 0; */
331
332
333 /* Since there isn't any equivalence in 0.71 */
334 /* and since Big_sur had to support legacy */
335
336 FADT2->iapc_boot_arch = BAF_LEGACY_DEVICES;
337
338 /* Copy to ACPI 2.0 64-BIT Extended Addresses */
339
340 FADT2->Xfirmware_ctrl = FADT71->firmware_ctrl;
341 FADT2->Xdsdt = FADT71->dsdt;
342
343
344 /* Extract the address space IDs */
345
346 pm1_address_space = (u8)((FADT71->address_space & PM1_BLK_ADDRESS_SPACE) >> 1);
347 pm2_address_space = (u8)((FADT71->address_space & PM2_CNT_BLK_ADDRESS_SPACE) >> 2);
348 pm_timer_address_space = (u8)((FADT71->address_space & PM_TMR_BLK_ADDRESS_SPACE) >> 3);
349 gpe0address_space = (u8)((FADT71->address_space & GPE0_BLK_ADDRESS_SPACE) >> 4);
350 gpe1_address_space = (u8)((FADT71->address_space & GPE1_BLK_ADDRESS_SPACE) >> 5);
351
352 /*
353 * Convert the 0.71 (non-GAS style) Block addresses to V2.0 GAS structures,
354 * in this order:
355 *
356 * PM 1_a Events
357 * PM 1_b Events
358 * PM 1_a Control
359 * PM 1_b Control
360 * PM 2 Control
361 * PM Timer Control
362 * GPE Block 0
363 * GPE Block 1
364 */
365
366 ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xpm1a_evt_blk, FADT71->pm1_evt_len, FADT71->pm1a_evt_blk, pm1_address_space);
367 ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xpm1b_evt_blk, FADT71->pm1_evt_len, FADT71->pm1b_evt_blk, pm1_address_space);
368 ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xpm1a_cnt_blk, FADT71->pm1_cnt_len, FADT71->pm1a_cnt_blk, pm1_address_space);
369 ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xpm1b_cnt_blk, FADT71->pm1_cnt_len, FADT71->pm1b_cnt_blk, pm1_address_space);
370 ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xpm2_cnt_blk, FADT71->pm2_cnt_len, FADT71->pm2_cnt_blk, pm2_address_space);
371 ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xpm_tmr_blk, FADT71->pm_tm_len, FADT71->pm_tmr_blk, pm_timer_address_space);
372 ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xgpe0blk, FADT71->gpe0blk_len, FADT71->gpe0blk, gpe0address_space);
373 ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xgpe1_blk, FADT71->gpe1_blk_len, FADT71->gpe1_blk, gpe1_address_space);
374
375 #else
376
377 /* ACPI 1.0 FACS */
378
379
380 /* The BIOS stored FADT should agree with Revision 1.0 */
381
382 FADT1 = (fadt_descriptor_rev1*) acpi_gbl_FADT;
383
384 /*
385 * Copy the table header and the common part of the tables
386 * The 2.0 table is an extension of the 1.0 table, so the
387 * entire 1.0 table can be copied first, then expand some
388 * fields to 64 bits.
389 */
390 MEMCPY (FADT2, FADT1, sizeof (fadt_descriptor_rev1));
391
392
393 /* Convert table pointers to 64-bit fields */
394
395 ACPI_STORE_ADDRESS (FADT2->Xfirmware_ctrl, FADT1->firmware_ctrl);
396 ACPI_STORE_ADDRESS (FADT2->Xdsdt, FADT1->dsdt);
397
398 /* System Interrupt Model isn't used in ACPI 2.0*/
399 /* FADT2->Reserved1 = 0; */
400
401 /* This field is set by the OEM to convey the preferred */
402 /* power management profile to OSPM. It doesn't have any*/
403 /* 1.0 equivalence. Since we don't know what kind of */
404 /* 32-bit system this is, we will pick unspecified. */
405
406 FADT2->prefer_PM_profile = PM_UNSPECIFIED;
407
408
409 /* Processor Performance State Control. This is the value */
410 /* OSPM writes to the SMI_CMD register to assume processor */
411 /* performance state control responsibility. There isn't */
412 /* any equivalence in 1.0. So leave it zeroed. */
413
414 FADT2->pstate_cnt = 0;
415
416
417 /* Support for the _CST object and C States change notification.*/
418 /* This data item hasn't any 1.0 equivalence so leaving it zero.*/
419
420 FADT2->cst_cnt = 0;
421
422
423 /* Since there isn't any equivalence in 1.0 and since it */
424 /* is highly likely that a 1.0 system has legacy support. */
425
426 FADT2->iapc_boot_arch = BAF_LEGACY_DEVICES;
427
428
429 /*
430 * Convert the V1.0 Block addresses to V2.0 GAS structures
431 * in this order:
432 *
433 * PM 1_a Events
434 * PM 1_b Events
435 * PM 1_a Control
436 * PM 1_b Control
437 * PM 2 Control
438 * PM Timer Control
439 * GPE Block 0
440 * GPE Block 1
441 */
442
443 ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xpm1a_evt_blk, FADT1->pm1_evt_len, FADT1->pm1a_evt_blk);
444 ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xpm1b_evt_blk, FADT1->pm1_evt_len, FADT1->pm1b_evt_blk);
445 ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xpm1a_cnt_blk, FADT1->pm1_cnt_len, FADT1->pm1a_cnt_blk);
446 ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xpm1b_cnt_blk, FADT1->pm1_cnt_len, FADT1->pm1b_cnt_blk);
447 ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xpm2_cnt_blk, FADT1->pm2_cnt_len, FADT1->pm2_cnt_blk);
448 ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xpm_tmr_blk, FADT1->pm_tm_len, FADT1->pm_tmr_blk);
449 ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xgpe0blk, FADT1->gpe0blk_len, FADT1->gpe0blk);
450 ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xgpe1_blk, FADT1->gpe1_blk_len, FADT1->gpe1_blk);
451 #endif
452 }
453
454
455 /*
456 * Global FADT pointer will point to the common V2.0 FADT
457 */
458 acpi_gbl_FADT = FADT2;
459 acpi_gbl_FADT->header.length = sizeof (FADT_DESCRIPTOR);
460
461
462 /* Free the original table */
463
464 table_desc = &acpi_gbl_acpi_tables[ACPI_TABLE_FADT];
465 acpi_tb_delete_single_table (table_desc);
466
467
468 /* Install the new table */
469
470 table_desc->pointer = (acpi_table_header *) acpi_gbl_FADT;
471 table_desc->base_pointer = acpi_gbl_FADT;
472 table_desc->allocation = ACPI_MEM_ALLOCATED;
473 table_desc->length = sizeof (fadt_descriptor_rev2);
474
475
476 /* Dump the entire FADT */
477
478 ACPI_DEBUG_PRINT ((ACPI_DB_TABLES,
479 "Hex dump of common internal FADT, size %ld (%lX)\n",
480 acpi_gbl_FADT->header.length, acpi_gbl_FADT->header.length));
481 DUMP_BUFFER ((u8 *) (acpi_gbl_FADT), acpi_gbl_FADT->header.length);
482
483
484 return_ACPI_STATUS (AE_OK);
485 }
486
487
488 /*******************************************************************************
489 *
490 * FUNCTION: Acpi_tb_convert_table_facs
491 *
492 * PARAMETERS:
493 *
494 * RETURN:
495 *
496 * DESCRIPTION:
497 *
498 ******************************************************************************/
499
500 acpi_status
501 acpi_tb_build_common_facs (
502 acpi_table_desc *table_info)
503 {
504 acpi_common_facs *common_facs;
505
506 #ifdef _IA64
507 facs_descriptor_rev071 *FACS71;
508 #else
509 facs_descriptor_rev1 *FACS1;
510 #endif
511
512 facs_descriptor_rev2 *FACS2;
513
514
515 FUNCTION_TRACE ("Tb_build_common_facs");
516
517
518 /* Allocate a common FACS */
519
520 common_facs = ACPI_MEM_CALLOCATE (sizeof (acpi_common_facs));
521 if (!common_facs) {
522 return_ACPI_STATUS (AE_NO_MEMORY);
523 }
524
525
526 /* Copy fields to the new FACS */
527
528 if (acpi_gbl_RSDP->revision < 2) {
529 #ifdef _IA64
530 /* 0.71 FACS */
531
532 FACS71 = (facs_descriptor_rev071 *) acpi_gbl_FACS;
533
534 common_facs->global_lock = (u32 *) &(FACS71->global_lock);
535 common_facs->firmware_waking_vector = &FACS71->firmware_waking_vector;
536 common_facs->vector_width = 64;
537 #else
538 /* ACPI 1.0 FACS */
539
540 FACS1 = (facs_descriptor_rev1 *) acpi_gbl_FACS;
541
542 common_facs->global_lock = &(FACS1->global_lock);
543 common_facs->firmware_waking_vector = (UINT64 *) &FACS1->firmware_waking_vector;
544 common_facs->vector_width = 32;
545
546 #endif
547 }
548
549 else {
550 /* ACPI 2.0 FACS */
551
552 FACS2 = (facs_descriptor_rev2 *) acpi_gbl_FACS;
553
554 common_facs->global_lock = &(FACS2->global_lock);
555 common_facs->firmware_waking_vector = &FACS2->Xfirmware_waking_vector;
556 common_facs->vector_width = 64;
557 }
558
559
560 /* Set the global FACS pointer to point to the common FACS */
561
562
563 acpi_gbl_FACS = common_facs;
564
565 return_ACPI_STATUS (AE_OK);
566 }
567
568
569