ReactOS Fundraising Campaign 2012
 
€ 3,873 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

tbconvrt.c
Go to the documentation of this file.
00001 /******************************************************************************
00002  *
00003  * Module Name: tbconvrt - ACPI Table conversion utilities
00004  *              $Revision: 1.1 $
00005  *
00006  *****************************************************************************/
00007 
00008 /*
00009  *  Copyright (C) 2000, 2001 R. Byron Moore
00010  *
00011  *  This program is free software; you can redistribute it and/or modify
00012  *  it under the terms of the GNU General Public License as published by
00013  *  the Free Software Foundation; either version 2 of the License, or
00014  *  (at your option) any later version.
00015  *
00016  *  This program is distributed in the hope that it will be useful,
00017  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  *  GNU General Public License for more details.
00020  *
00021  *  You should have received a copy of the GNU General Public License
00022  *  along with this program; if not, write to the Free Software
00023  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00024  */
00025 
00026 
00027 #include <acpi.h>
00028 
00029 #define _COMPONENT          ACPI_TABLES
00030      MODULE_NAME         ("tbconvrt")
00031 
00032 
00033 /*
00034  * Build a GAS structure from earlier ACPI table entries (V1.0 and 0.71 extensions)
00035  *
00036  * 1) Address space
00037  * 2) Length in bytes -- convert to length in bits
00038  * 3) Bit offset is zero
00039  * 4) Reserved field is zero
00040  * 5) Expand address to 64 bits
00041  */
00042 #define ASL_BUILD_GAS_FROM_ENTRY(a,b,c,d)   {a.address_space_id = (u8) d;\
00043                a.register_bit_width = (u8) MUL_8 (b);\
00044                a.register_bit_offset = 0;\
00045                a.reserved = 0;\
00046                ACPI_STORE_ADDRESS (a.address,c);}
00047 
00048 
00049 /* ACPI V1.0 entries -- address space is always I/O */
00050 
00051 #define ASL_BUILD_GAS_FROM_V1_ENTRY(a,b,c)  ASL_BUILD_GAS_FROM_ENTRY(a,b,c,ADDRESS_SPACE_SYSTEM_IO)
00052 
00053 
00054 /*******************************************************************************
00055  *
00056  * FUNCTION:    Acpi_tb_convert_to_xsdt
00057  *
00058  * PARAMETERS:
00059  *
00060  * RETURN:
00061  *
00062  * DESCRIPTION:
00063  *
00064  ******************************************************************************/
00065 
00066 ACPI_STATUS
00067 acpi_tb_convert_to_xsdt (
00068     ACPI_TABLE_DESC         *table_info,
00069     u32                     *number_of_tables) {
00070     u32                     table_size;
00071     u32                     pointer_size;
00072     u32                     i;
00073     XSDT_DESCRIPTOR         *new_table;
00074 
00075 
00076 #ifndef _IA64
00077 
00078     if (acpi_gbl_RSDP->revision < 2) {
00079         pointer_size = sizeof (u32);
00080     }
00081 
00082     else
00083 #endif
00084     {
00085         pointer_size = sizeof (UINT64);
00086     }
00087 
00088     /*
00089      * Determine the number of tables pointed to by the RSDT/XSDT.
00090      * This is defined by the ACPI Specification to be the number of
00091      * pointers contained within the RSDT/XSDT.  The size of the pointers
00092      * is architecture-dependent.
00093      */
00094 
00095     table_size = table_info->pointer->length;
00096     *number_of_tables = (table_size -
00097                sizeof (ACPI_TABLE_HEADER)) / pointer_size;
00098 
00099     /* Compute size of the converted XSDT */
00100 
00101     table_size = (*number_of_tables * sizeof (UINT64)) + sizeof (ACPI_TABLE_HEADER);
00102 
00103 
00104     /* Allocate an XSDT */
00105 
00106     new_table = acpi_cm_callocate (table_size);
00107     if (!new_table) {
00108         return (AE_NO_MEMORY);
00109     }
00110 
00111     /* Copy the header and set the length */
00112 
00113     MEMCPY (new_table, table_info->pointer, sizeof (ACPI_TABLE_HEADER));
00114     new_table->header.length = table_size;
00115 
00116     /* Copy the table pointers */
00117 
00118     for (i = 0; i < *number_of_tables; i++) {
00119         if (acpi_gbl_RSDP->revision < 2) {
00120 #ifdef _IA64
00121             new_table->table_offset_entry[i] =
00122                 ((RSDT_DESCRIPTOR_REV071 *) table_info->pointer)->table_offset_entry[i];
00123 #else
00124             ACPI_STORE_ADDRESS (new_table->table_offset_entry[i],
00125                 ((RSDT_DESCRIPTOR_REV1 *) table_info->pointer)->table_offset_entry[i]);
00126 #endif
00127         }
00128         else {
00129             new_table->table_offset_entry[i] =
00130                 ((XSDT_DESCRIPTOR *) table_info->pointer)->table_offset_entry[i];
00131         }
00132     }
00133 
00134 
00135     /* Delete the original table (either mapped or in a buffer) */
00136 
00137     acpi_tb_delete_single_table (table_info);
00138 
00139 
00140     /* Point the table descriptor to the new table */
00141 
00142     table_info->pointer     = (ACPI_TABLE_HEADER *) new_table;
00143     table_info->base_pointer = (ACPI_TABLE_HEADER *) new_table;
00144     table_info->length      = table_size;
00145     table_info->allocation  = ACPI_MEM_ALLOCATED;
00146 
00147     return (AE_OK);
00148 }
00149 
00150 
00151 /*******************************************************************************
00152  *
00153  * FUNCTION:    Acpi_tb_convert_table_fadt
00154  *
00155  * PARAMETERS:
00156  *
00157  * RETURN:
00158  *
00159  * DESCRIPTION:
00160  *    Converts BIOS supplied 1.0 and 0.71 ACPI FADT to an intermediate
00161  *    ACPI 2.0 FADT. If the BIOS supplied a 2.0 FADT then it is simply
00162  *    copied to the intermediate FADT.  The ACPI CA software uses this
00163  *    intermediate FADT. Thus a significant amount of special #ifdef
00164  *    type codeing is saved. This intermediate FADT will need to be
00165  *    freed at some point.
00166  *
00167  ******************************************************************************/
00168 
00169 ACPI_STATUS
00170 acpi_tb_convert_table_fadt (void)
00171 {
00172 
00173 #ifdef _IA64
00174     FADT_DESCRIPTOR_REV071 *FADT71;
00175     u8                      pm1_address_space;
00176     u8                      pm2_address_space;
00177     u8                      pm_timer_address_space;
00178     u8                      gpe0address_space;
00179     u8                      gpe1_address_space;
00180 #else
00181     FADT_DESCRIPTOR_REV1   *FADT1;
00182 #endif
00183 
00184     FADT_DESCRIPTOR_REV2   *FADT2;
00185     ACPI_TABLE_DESC        *table_desc;
00186 
00187 
00188     /* Acpi_gbl_FADT is valid */
00189     /* Allocate and zero the 2.0 buffer */
00190 
00191     FADT2 = acpi_cm_callocate (sizeof (FADT_DESCRIPTOR_REV2));
00192     if (FADT2 == NULL) {
00193         return (AE_NO_MEMORY);
00194     }
00195 
00196 
00197     /* The ACPI FADT revision number is FADT2_REVISION_ID=3 */
00198     /* So, if the current table revision is less than 3 it is type 1.0 or 0.71 */
00199 
00200     if (acpi_gbl_FADT->header.revision >= FADT2_REVISION_ID) {
00201         /* We have an ACPI 2.0 FADT but we must copy it to our local buffer */
00202 
00203         *FADT2 = *((FADT_DESCRIPTOR_REV2*) acpi_gbl_FADT);
00204 
00205     }
00206 
00207     else {
00208 
00209 #ifdef _IA64
00210         /*
00211          * For the 64-bit case only, a revision ID less than V2.0 means the
00212          * tables are the 0.71 extensions
00213          */
00214 
00215         /* The BIOS stored FADT should agree with Revision 0.71 */
00216 
00217         FADT71 = (FADT_DESCRIPTOR_REV071 *) acpi_gbl_FADT;
00218 
00219         /* Copy the table header*/
00220 
00221         FADT2->header       = FADT71->header;
00222 
00223         /* Copy the common fields */
00224 
00225         FADT2->sci_int      = FADT71->sci_int;
00226         FADT2->acpi_enable  = FADT71->acpi_enable;
00227         FADT2->acpi_disable = FADT71->acpi_disable;
00228         FADT2->S4_bios_req  = FADT71->S4_bios_req;
00229         FADT2->plvl2_lat    = FADT71->plvl2_lat;
00230         FADT2->plvl3_lat    = FADT71->plvl3_lat;
00231         FADT2->day_alrm     = FADT71->day_alrm;
00232         FADT2->mon_alrm     = FADT71->mon_alrm;
00233         FADT2->century      = FADT71->century;
00234         FADT2->gpe1_base    = FADT71->gpe1_base;
00235 
00236         /*
00237          * We still use the block length registers even though
00238          * the GAS structure should obsolete them.  This is because
00239          * these registers are byte lengths versus the GAS which
00240          * contains a bit width
00241          */
00242         FADT2->pm1_evt_len  = FADT71->pm1_evt_len;
00243         FADT2->pm1_cnt_len  = FADT71->pm1_cnt_len;
00244         FADT2->pm2_cnt_len  = FADT71->pm2_cnt_len;
00245         FADT2->pm_tm_len    = FADT71->pm_tm_len;
00246         FADT2->gpe0blk_len  = FADT71->gpe0blk_len;
00247         FADT2->gpe1_blk_len = FADT71->gpe1_blk_len;
00248         FADT2->gpe1_base    = FADT71->gpe1_base;
00249 
00250         /* Copy the existing 0.71 flags to 2.0. The other bits are zero.*/
00251 
00252         FADT2->wb_invd      = FADT71->flush_cash;
00253         FADT2->proc_c1      = FADT71->proc_c1;
00254         FADT2->plvl2_up     = FADT71->plvl2_up;
00255         FADT2->pwr_button   = FADT71->pwr_button;
00256         FADT2->sleep_button = FADT71->sleep_button;
00257         FADT2->fixed_rTC    = FADT71->fixed_rTC;
00258         FADT2->rtcs4        = FADT71->rtcs4;
00259         FADT2->tmr_val_ext  = FADT71->tmr_val_ext;
00260         FADT2->dock_cap     = FADT71->dock_cap;
00261 
00262 
00263         /* We should not use these next two addresses */
00264         /* Since our buffer is pre-zeroed nothing to do for */
00265         /* the next three data items in the structure */
00266         /* FADT2->Firmware_ctrl = 0; */
00267         /* FADT2->Dsdt = 0; */
00268 
00269         /* System Interrupt Model isn't used in ACPI 2.0*/
00270         /* FADT2->Reserved1 = 0; */
00271 
00272         /* This field is set by the OEM to convey the preferred */
00273         /* power management profile to OSPM. It doesn't have any*/
00274         /* 0.71 equivalence.  Since we don't know what kind of  */
00275         /* 64-bit system this is, we will pick unspecified.     */
00276 
00277         FADT2->prefer_PM_profile = PM_UNSPECIFIED;
00278 
00279 
00280         /* Port address of SMI command port */
00281         /* We shouldn't use this port because IA64 doesn't */
00282         /* have or use SMI.  It has PMI. */
00283 
00284         FADT2->smi_cmd      = (u32)(FADT71->smi_cmd & 0xFFFFFFFF);
00285 
00286 
00287         /* processor performance state control*/
00288         /* The value OSPM writes to the SMI_CMD register to assume */
00289         /* processor performance state control responsibility. */
00290         /* There isn't any equivalence in 0.71 */
00291         /* Again this should be meaningless for IA64 */
00292         /* FADT2->Pstate_cnt = 0; */
00293 
00294         /* The 32-bit Power management and GPE registers are */
00295         /* not valid in IA-64 and we are not going to use them */
00296         /* so leaving them pre-zeroed. */
00297 
00298         /* Support for the _CST object and C States change notification.*/
00299         /* This data item hasn't any 0.71 equivalence so leaving it zero.*/
00300         /* FADT2->Cst_cnt = 0; */
00301 
00302         /* number of flush strides that need to be read */
00303         /* No 0.71 equivalence. Leave pre-zeroed. */
00304         /* FADT2->Flush_size = 0; */
00305 
00306         /* Processor's memory cache line width, in bytes */
00307         /* No 0.71 equivalence. Leave pre-zeroed. */
00308         /* FADT2->Flush_stride = 0; */
00309 
00310         /* Processor's duty cycle index in processor's P_CNT reg*/
00311         /* No 0.71 equivalence. Leave pre-zeroed. */
00312         /* FADT2->Duty_offset = 0; */
00313 
00314         /* Processor's duty cycle value bit width in P_CNT register.*/
00315         /* No 0.71 equivalence. Leave pre-zeroed. */
00316         /* FADT2->Duty_width = 0; */
00317 
00318 
00319         /* Since there isn't any equivalence in 0.71 */
00320         /* and since Big_sur had to support legacy */
00321 
00322         FADT2->iapc_boot_arch = BAF_LEGACY_DEVICES;
00323 
00324         /* Copy to ACPI 2.0 64-BIT Extended Addresses */
00325 
00326         FADT2->Xfirmware_ctrl = FADT71->firmware_ctrl;
00327         FADT2->Xdsdt         = FADT71->dsdt;
00328 
00329 
00330         /* Extract the address space IDs */
00331 
00332         pm1_address_space   = (u8)((FADT71->address_space & PM1_BLK_ADDRESS_SPACE)    >> 1);
00333         pm2_address_space   = (u8)((FADT71->address_space & PM2_CNT_BLK_ADDRESS_SPACE) >> 2);
00334         pm_timer_address_space = (u8)((FADT71->address_space & PM_TMR_BLK_ADDRESS_SPACE) >> 3);
00335         gpe0address_space   = (u8)((FADT71->address_space & GPE0_BLK_ADDRESS_SPACE)   >> 4);
00336         gpe1_address_space  = (u8)((FADT71->address_space & GPE1_BLK_ADDRESS_SPACE)   >> 5);
00337 
00338         /*
00339          * Convert the 0.71 (non-GAS style) Block addresses to V2.0 GAS structures,
00340          * in this order:
00341          *
00342          * PM 1_a Events
00343          * PM 1_b Events
00344          * PM 1_a Control
00345          * PM 1_b Control
00346          * PM 2 Control
00347          * PM Timer Control
00348          * GPE Block 0
00349          * GPE Block 1
00350          */
00351 
00352         ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xpm1a_evt_blk, FADT71->pm1_evt_len, FADT71->pm1a_evt_blk, pm1_address_space);
00353         ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xpm1b_evt_blk, FADT71->pm1_evt_len, FADT71->pm1b_evt_blk, pm1_address_space);
00354         ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xpm1a_cnt_blk, FADT71->pm1_cnt_len, FADT71->pm1a_cnt_blk, pm1_address_space);
00355         ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xpm1b_cnt_blk, FADT71->pm1_cnt_len, FADT71->pm1b_cnt_blk, pm1_address_space);
00356         ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xpm2_cnt_blk, FADT71->pm2_cnt_len, FADT71->pm2_cnt_blk, pm2_address_space);
00357         ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xpm_tmr_blk, FADT71->pm_tm_len,  FADT71->pm_tmr_blk, pm_timer_address_space);
00358         ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xgpe0blk,    FADT71->gpe0blk_len, FADT71->gpe0blk,   gpe0address_space);
00359         ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xgpe1_blk,   FADT71->gpe1_blk_len, FADT71->gpe1_blk, gpe1_address_space);
00360 
00361 #else
00362 
00363         /* ACPI 1.0 FACS */
00364 
00365 
00366         /* The BIOS stored FADT should agree with Revision 1.0 */
00367 
00368         FADT1 = (FADT_DESCRIPTOR_REV1*) acpi_gbl_FADT;
00369 
00370         /*
00371          * Copy the table header and the common part of the tables
00372          * The 2.0 table is an extension of the 1.0 table, so the
00373          * entire 1.0 table can be copied first, then expand some
00374          * fields to 64 bits.
00375          */
00376 
00377         MEMCPY (FADT2, FADT1, sizeof (FADT_DESCRIPTOR_REV1));
00378 
00379 
00380         /* Convert table pointers to 64-bit fields */
00381 
00382         ACPI_STORE_ADDRESS (FADT2->Xfirmware_ctrl, FADT1->firmware_ctrl);
00383         ACPI_STORE_ADDRESS (FADT2->Xdsdt, FADT1->dsdt);
00384 
00385         /* System Interrupt Model isn't used in ACPI 2.0*/
00386         /* FADT2->Reserved1 = 0; */
00387 
00388         /* This field is set by the OEM to convey the preferred */
00389         /* power management profile to OSPM. It doesn't have any*/
00390         /* 1.0 equivalence.  Since we don't know what kind of   */
00391         /* 32-bit system this is, we will pick unspecified.     */
00392 
00393         FADT2->prefer_PM_profile = PM_UNSPECIFIED;
00394 
00395 
00396         /* Processor Performance State Control. This is the value  */
00397         /* OSPM writes to the SMI_CMD register to assume processor */
00398         /* performance state control responsibility. There isn't   */
00399         /* any equivalence in 1.0.  So leave it zeroed.            */
00400 
00401         FADT2->pstate_cnt = 0;
00402 
00403 
00404         /* Support for the _CST object and C States change notification.*/
00405         /* This data item hasn't any 1.0 equivalence so leaving it zero.*/
00406 
00407         FADT2->cst_cnt = 0;
00408 
00409 
00410         /* Since there isn't any equivalence in 1.0 and since it   */
00411         /* is highly likely that a 1.0 system has legacy  support. */
00412 
00413         FADT2->iapc_boot_arch = BAF_LEGACY_DEVICES;
00414 
00415 
00416         /*
00417          * Convert the V1.0 Block addresses to V2.0 GAS structures
00418          * in this order:
00419          *
00420          * PM 1_a Events
00421          * PM 1_b Events
00422          * PM 1_a Control
00423          * PM 1_b Control
00424          * PM 2 Control
00425          * PM Timer Control
00426          * GPE Block 0
00427          * GPE Block 1
00428          */
00429 
00430         ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xpm1a_evt_blk, FADT1->pm1_evt_len, FADT1->pm1a_evt_blk);
00431         ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xpm1b_evt_blk, FADT1->pm1_evt_len, FADT1->pm1b_evt_blk);
00432         ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xpm1a_cnt_blk, FADT1->pm1_cnt_len, FADT1->pm1a_cnt_blk);
00433         ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xpm1b_cnt_blk, FADT1->pm1_cnt_len, FADT1->pm1b_cnt_blk);
00434         ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xpm2_cnt_blk, FADT1->pm2_cnt_len, FADT1->pm2_cnt_blk);
00435         ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xpm_tmr_blk, FADT1->pm_tm_len,  FADT1->pm_tmr_blk);
00436         ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xgpe0blk,    FADT1->gpe0blk_len, FADT1->gpe0blk);
00437         ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xgpe1_blk,   FADT1->gpe1_blk_len, FADT1->gpe1_blk);
00438 #endif
00439     }
00440 
00441 
00442     /*
00443      * Global FADT pointer will point to the common V2.0 FADT
00444      */
00445     acpi_gbl_FADT = FADT2;
00446     acpi_gbl_FADT->header.length = sizeof (FADT_DESCRIPTOR);
00447 
00448 
00449     /* Free the original table */
00450 
00451     table_desc = &acpi_gbl_acpi_tables[ACPI_TABLE_FADT];
00452     acpi_tb_delete_single_table (table_desc);
00453 
00454 
00455     /* Install the new table */
00456 
00457     table_desc->pointer = (ACPI_TABLE_HEADER *) acpi_gbl_FADT;
00458     table_desc->base_pointer = acpi_gbl_FADT;
00459     table_desc->allocation = ACPI_MEM_ALLOCATED;
00460     table_desc->length = sizeof (FADT_DESCRIPTOR_REV2);
00461 
00462 
00463     /* Dump the entire FADT */
00464 
00465 
00466     return (AE_OK);
00467 }
00468 
00469 
00470 /*******************************************************************************
00471  *
00472  * FUNCTION:    Acpi_tb_convert_table_facs
00473  *
00474  * PARAMETERS:
00475  *
00476  * RETURN:
00477  *
00478  * DESCRIPTION:
00479  *
00480  ******************************************************************************/
00481 
00482 ACPI_STATUS
00483 acpi_tb_build_common_facs (
00484     ACPI_TABLE_DESC         *table_info)
00485 {
00486     ACPI_COMMON_FACS        *common_facs;
00487 
00488 #ifdef _IA64
00489     FACS_DESCRIPTOR_REV071  *FACS71;
00490 #else
00491     FACS_DESCRIPTOR_REV1    *FACS1;
00492 #endif
00493 
00494     FACS_DESCRIPTOR_REV2    *FACS2;
00495 
00496 
00497     /* Allocate a common FACS */
00498 
00499     common_facs = acpi_cm_callocate (sizeof (ACPI_COMMON_FACS));
00500     if (!common_facs) {
00501         return (AE_NO_MEMORY);
00502     }
00503 
00504 
00505     /* Copy fields to the new FACS */
00506 
00507     if (acpi_gbl_RSDP->revision < 2) {
00508 #ifdef _IA64
00509         /* 0.71 FACS */
00510 
00511         FACS71 = (FACS_DESCRIPTOR_REV071 *) acpi_gbl_FACS;
00512 
00513         common_facs->global_lock = (u32 *) &(FACS71->global_lock);
00514         common_facs->firmware_waking_vector = &FACS71->firmware_waking_vector;
00515         common_facs->vector_width = 64;
00516 #else
00517         /* ACPI 1.0 FACS */
00518 
00519         FACS1 = (FACS_DESCRIPTOR_REV1 *) acpi_gbl_FACS;
00520 
00521         common_facs->global_lock = &(FACS1->global_lock);
00522         common_facs->firmware_waking_vector = (UINT64 *) &FACS1->firmware_waking_vector;
00523         common_facs->vector_width = 32;
00524 
00525 #endif
00526     }
00527 
00528     else {
00529         /* ACPI 2.0 FACS */
00530 
00531         FACS2 = (FACS_DESCRIPTOR_REV2 *) acpi_gbl_FACS;
00532 
00533         common_facs->global_lock = &(FACS2->global_lock);
00534         common_facs->firmware_waking_vector = &FACS2->Xfirmware_waking_vector;
00535         common_facs->vector_width = 64;
00536     }
00537 
00538 
00539     /* Set the global FACS pointer to point to the common FACS */
00540 
00541 
00542     acpi_gbl_FACS = common_facs;
00543 
00544     return  (AE_OK);
00545 }
00546 
00547 

Generated on Sat May 19 2012 04:25:18 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.