tbconvrt.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:16k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

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