ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 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

tbget.c
Go to the documentation of this file.
00001 /******************************************************************************
00002  *
00003  * Module Name: tbget - ACPI Table get* routines
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         ("tbget")
00031 
00032 #define RSDP_CHECKSUM_LENGTH 20
00033 
00034 /*******************************************************************************
00035  *
00036  * FUNCTION:    Acpi_tb_get_table_ptr
00037  *
00038  * PARAMETERS:  Table_type      - one of the defined table types
00039  *              Instance        - Which table of this type
00040  *              Table_ptr_loc   - pointer to location to place the pointer for
00041  *                                return
00042  *
00043  * RETURN:      Status
00044  *
00045  * DESCRIPTION: This function is called to get the pointer to an ACPI table.
00046  *
00047  ******************************************************************************/
00048 
00049 ACPI_STATUS
00050 acpi_tb_get_table_ptr (
00051     ACPI_TABLE_TYPE         table_type,
00052     u32                     instance,
00053     ACPI_TABLE_HEADER       **table_ptr_loc)
00054 {
00055     ACPI_TABLE_DESC         *table_desc;
00056     u32                     i;
00057 
00058 
00059     if (!acpi_gbl_DSDT) {
00060         return (AE_NO_ACPI_TABLES);
00061     }
00062 
00063     if (table_type > ACPI_TABLE_MAX) {
00064         return (AE_BAD_PARAMETER);
00065     }
00066 
00067 
00068     /*
00069      * For all table types (Single/Multiple), the first
00070      * instance is always in the list head.
00071      */
00072 
00073     if (instance == 1) {
00074         /*
00075          * Just pluck the pointer out of the global table!
00076          * Will be null if no table is present
00077          */
00078 
00079         *table_ptr_loc = acpi_gbl_acpi_tables[table_type].pointer;
00080         return (AE_OK);
00081     }
00082 
00083 
00084     /*
00085      * Check for instance out of range
00086      */
00087     if (instance > acpi_gbl_acpi_tables[table_type].count) {
00088         return (AE_NOT_EXIST);
00089     }
00090 
00091     /* Walk the list to get the desired table
00092      *  Since the if (Instance == 1) check above checked for the
00093      *  first table, setting Table_desc equal to the .Next member
00094      *  is actually pointing to the second table.  Therefore, we
00095      *  need to walk from the 2nd table until we reach the Instance
00096      *  that the user is looking for and return its table pointer.
00097      */
00098     table_desc = acpi_gbl_acpi_tables[table_type].next;
00099     for (i = 2; i < instance; i++) {
00100         table_desc = table_desc->next;
00101     }
00102 
00103     /* We are now pointing to the requested table's descriptor */
00104 
00105     *table_ptr_loc = table_desc->pointer;
00106 
00107     return (AE_OK);
00108 }
00109 
00110 
00111 /*******************************************************************************
00112  *
00113  * FUNCTION:    Acpi_tb_get_table
00114  *
00115  * PARAMETERS:  Physical_address        - Physical address of table to retrieve
00116  *              *Buffer_ptr             - If Buffer_ptr is valid, read data from
00117  *                                         buffer rather than searching memory
00118  *              *Table_info             - Where the table info is returned
00119  *
00120  * RETURN:      Status
00121  *
00122  * DESCRIPTION: Maps the physical address of table into a logical address
00123  *
00124  ******************************************************************************/
00125 
00126 ACPI_STATUS
00127 acpi_tb_get_table (
00128     ACPI_PHYSICAL_ADDRESS   physical_address,
00129     ACPI_TABLE_HEADER       *buffer_ptr,
00130     ACPI_TABLE_DESC         *table_info)
00131 {
00132     ACPI_TABLE_HEADER       *table_header = NULL;
00133     ACPI_TABLE_HEADER       *full_table = NULL;
00134     u32                     size;
00135     u8                      allocation;
00136     ACPI_STATUS             status = AE_OK;
00137 
00138 
00139     if (!table_info) {
00140         return (AE_BAD_PARAMETER);
00141     }
00142 
00143 
00144     if (buffer_ptr) {
00145         /*
00146          * Getting data from a buffer, not BIOS tables
00147          */
00148 
00149         table_header = buffer_ptr;
00150         status = acpi_tb_validate_table_header (table_header);
00151         if (ACPI_FAILURE (status)) {
00152             /* Table failed verification, map all errors to BAD_DATA */
00153 
00154             return (AE_BAD_DATA);
00155         }
00156 
00157         /* Allocate buffer for the entire table */
00158 
00159         full_table = acpi_cm_allocate (table_header->length);
00160         if (!full_table) {
00161             return (AE_NO_MEMORY);
00162         }
00163 
00164         /* Copy the entire table (including header) to the local buffer */
00165 
00166         size = table_header->length;
00167         MEMCPY (full_table, buffer_ptr, size);
00168 
00169         /* Save allocation type */
00170 
00171         allocation = ACPI_MEM_ALLOCATED;
00172     }
00173 
00174 
00175     /*
00176      * Not reading from a buffer, just map the table's physical memory
00177      * into our address space.
00178      */
00179     else {
00180         size = SIZE_IN_HEADER;
00181 
00182         status = acpi_tb_map_acpi_table (physical_address, &size,
00183                   (void **) &full_table);
00184         if (ACPI_FAILURE (status)) {
00185             return (status);
00186         }
00187 
00188         /* Save allocation type */
00189 
00190         allocation = ACPI_MEM_MAPPED;
00191     }
00192 
00193 
00194     /* Return values */
00195 
00196     table_info->pointer     = full_table;
00197     table_info->length      = size;
00198     table_info->allocation  = allocation;
00199     table_info->base_pointer = full_table;
00200 
00201     return (status);
00202 }
00203 
00204 
00205 /*******************************************************************************
00206  *
00207  * FUNCTION:    Acpi_tb_get_all_tables
00208  *
00209  * PARAMETERS:  Number_of_tables    - Number of tables to get
00210  *              Table_ptr           - Input buffer pointer, optional
00211  *
00212  * RETURN:      Status
00213  *
00214  * DESCRIPTION: Load and validate all tables other than the RSDT.  The RSDT must
00215  *              already be loaded and validated.
00216  *
00217  ******************************************************************************/
00218 
00219 ACPI_STATUS
00220 acpi_tb_get_all_tables (
00221     u32                     number_of_tables,
00222     ACPI_TABLE_HEADER       *table_ptr)
00223 {
00224     ACPI_STATUS             status = AE_OK;
00225     u32                     index;
00226     ACPI_TABLE_DESC         table_info;
00227 
00228 
00229     /*
00230      * Loop through all table pointers found in RSDT.
00231      * This will NOT include the FACS and DSDT - we must get
00232      * them after the loop
00233      */
00234 
00235     for (index = 0; index < number_of_tables; index++) {
00236         /* Clear the Table_info each time */
00237 
00238         MEMSET (&table_info, 0, sizeof (ACPI_TABLE_DESC));
00239 
00240         /* Get the table via the XSDT */
00241 
00242         status = acpi_tb_get_table ((ACPI_PHYSICAL_ADDRESS)
00243                  ACPI_GET_ADDRESS (acpi_gbl_XSDT->table_offset_entry[index]),
00244                  table_ptr, &table_info);
00245 
00246         /* Ignore a table that failed verification */
00247 
00248         if (status == AE_BAD_DATA) {
00249             continue;
00250         }
00251 
00252         /* However, abort on serious errors */
00253 
00254         if (ACPI_FAILURE (status)) {
00255             return (status);
00256         }
00257 
00258         /* Recognize and install the table */
00259 
00260         status = acpi_tb_install_table (table_ptr, &table_info);
00261         if (ACPI_FAILURE (status)) {
00262             /*
00263              * Unrecognized or unsupported table, delete it and ignore the
00264              * error.  Just get as many tables as we can, later we will
00265              * determine if there are enough tables to continue.
00266              */
00267 
00268             acpi_tb_uninstall_table (&table_info);
00269         }
00270     }
00271 
00272 
00273     /*
00274      * Convert the FADT to a common format.  This allows earlier revisions of the
00275      * table to coexist with newer versions, using common access code.
00276      */
00277     status = acpi_tb_convert_table_fadt ();
00278     if (ACPI_FAILURE (status)) {
00279         return (status);
00280     }
00281 
00282 
00283     /*
00284      * Get the minimum set of ACPI tables, namely:
00285      *
00286      * 1) FADT (via RSDT in loop above)
00287      * 2) FACS
00288      * 3) DSDT
00289      *
00290      */
00291 
00292 
00293     /*
00294      * Get the FACS (must have the FADT first, from loop above)
00295      * Acpi_tb_get_table_facs will fail if FADT pointer is not valid
00296      */
00297 
00298     status = acpi_tb_get_table_facs (table_ptr, &table_info);
00299     if (ACPI_FAILURE (status)) {
00300         return (status);
00301     }
00302 
00303 
00304     /* Install the FACS */
00305 
00306     status = acpi_tb_install_table (table_ptr, &table_info);
00307     if (ACPI_FAILURE (status)) {
00308         return (status);
00309     }
00310 
00311     /*
00312      * Create the common FACS pointer table
00313      * (Contains pointers to the original table)
00314      */
00315 
00316     status = acpi_tb_build_common_facs (&table_info);
00317     if (ACPI_FAILURE (status)) {
00318         return (status);
00319     }
00320 
00321 
00322     /*
00323      * Get the DSDT (We know that the FADT is valid now)
00324      */
00325 
00326     status = acpi_tb_get_table ((ACPI_PHYSICAL_ADDRESS) ACPI_GET_ADDRESS (acpi_gbl_FADT->Xdsdt),
00327               table_ptr, &table_info);
00328     if (ACPI_FAILURE (status)) {
00329         return (status);
00330     }
00331 
00332     /* Install the DSDT */
00333 
00334     status = acpi_tb_install_table (table_ptr, &table_info);
00335     if (ACPI_FAILURE (status)) {
00336         return (status);
00337     }
00338 
00339     /* Dump the DSDT Header */
00340 
00341     /* Dump the entire DSDT */
00342 
00343     /*
00344      * Initialize the capabilities flags.
00345      * Assumes that platform supports ACPI_MODE since we have tables!
00346      */
00347     acpi_gbl_system_flags |= acpi_hw_get_mode_capabilities ();
00348 
00349 
00350     /* Always delete the RSDP mapping, we are done with it */
00351 
00352     acpi_tb_delete_acpi_table (ACPI_TABLE_RSDP);
00353 
00354     return (status);
00355 }
00356 
00357 
00358 /*******************************************************************************
00359  *
00360  * FUNCTION:    Acpi_tb_verify_rsdp
00361  *
00362  * PARAMETERS:  Number_of_tables    - Where the table count is placed
00363  *
00364  * RETURN:      Status
00365  *
00366  * DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table)
00367  *
00368  ******************************************************************************/
00369 
00370 ACPI_STATUS
00371 acpi_tb_verify_rsdp (
00372     ACPI_PHYSICAL_ADDRESS   rsdp_physical_address)
00373 {
00374     ACPI_TABLE_DESC         table_info;
00375     ACPI_STATUS             status;
00376     u8                      *table_ptr;
00377 
00378 
00379     /*
00380      * Obtain access to the RSDP structure
00381      */
00382     status = acpi_os_map_memory (rsdp_physical_address,
00383               sizeof (RSDP_DESCRIPTOR),
00384               (void **) &table_ptr);
00385     if (ACPI_FAILURE (status)) {
00386         return (status);
00387     }
00388 
00389     /*
00390      *  The signature and checksum must both be correct
00391      */
00392     if (STRNCMP ((NATIVE_CHAR *) table_ptr, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0) {
00393         /* Nope, BAD Signature */
00394 
00395         status = AE_BAD_SIGNATURE;
00396         goto cleanup;
00397     }
00398 
00399     if (acpi_tb_checksum (table_ptr, RSDP_CHECKSUM_LENGTH) != 0) {
00400         /* Nope, BAD Checksum */
00401 
00402         status = AE_BAD_CHECKSUM;
00403         goto cleanup;
00404     }
00405 
00406     /* TBD: Check extended checksum if table version >= 2 */
00407 
00408     /* The RSDP supplied is OK */
00409 
00410     table_info.pointer     = (ACPI_TABLE_HEADER *) table_ptr;
00411     table_info.length      = sizeof (RSDP_DESCRIPTOR);
00412     table_info.allocation  = ACPI_MEM_MAPPED;
00413     table_info.base_pointer = table_ptr;
00414 
00415     /* Save the table pointers and allocation info */
00416 
00417     status = acpi_tb_init_table_descriptor (ACPI_TABLE_RSDP, &table_info);
00418     if (ACPI_FAILURE (status)) {
00419         goto cleanup;
00420     }
00421 
00422 
00423     /* Save the RSDP in a global for easy access */
00424 
00425     acpi_gbl_RSDP = (RSDP_DESCRIPTOR *) table_info.pointer;
00426     return (status);
00427 
00428 
00429     /* Error exit */
00430 cleanup:
00431 
00432     acpi_os_unmap_memory (table_ptr, sizeof (RSDP_DESCRIPTOR));
00433     return (status);
00434 }
00435 
00436 
00437 /*******************************************************************************
00438  *
00439  * FUNCTION:    Acpi_tb_get_table_rsdt
00440  *
00441  * PARAMETERS:  Number_of_tables    - Where the table count is placed
00442  *
00443  * RETURN:      Status
00444  *
00445  * DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table)
00446  *
00447  ******************************************************************************/
00448 
00449 ACPI_STATUS
00450 acpi_tb_get_table_rsdt (
00451     u32                     *number_of_tables)
00452 {
00453     ACPI_TABLE_DESC         table_info;
00454     ACPI_STATUS             status = AE_OK;
00455     ACPI_PHYSICAL_ADDRESS   physical_address;
00456     u32                     signature_length;
00457     char                    *table_signature;
00458 
00459 
00460     /*
00461      * Get the RSDT from the RSDP
00462      */
00463 
00464     /*
00465      * For RSDP revision 0 or 1, we use the RSDT.
00466      * For RSDP revision 2 (and above), we use the XSDT
00467      */
00468     if (acpi_gbl_RSDP->revision < 2) {
00469 #ifdef _IA64
00470         /* 0.71 RSDP has 64bit Rsdt address field */
00471         physical_address = ((RSDP_DESCRIPTOR_REV071 *)acpi_gbl_RSDP)->rsdt_physical_address;
00472 #else
00473         physical_address = (ACPI_PHYSICAL_ADDRESS) acpi_gbl_RSDP->rsdt_physical_address;
00474 #endif
00475         table_signature = RSDT_SIG;
00476         signature_length = sizeof (RSDT_SIG) -1;
00477     }
00478     else {
00479         physical_address = (ACPI_PHYSICAL_ADDRESS)
00480                    ACPI_GET_ADDRESS (acpi_gbl_RSDP->xsdt_physical_address);
00481         table_signature = XSDT_SIG;
00482         signature_length = sizeof (XSDT_SIG) -1;
00483     }
00484 
00485 
00486     /* Get the RSDT/XSDT */
00487 
00488     status = acpi_tb_get_table (physical_address, NULL, &table_info);
00489     if (ACPI_FAILURE (status)) {
00490         return (status);
00491     }
00492 
00493 
00494     /* Check the RSDT or XSDT signature */
00495 
00496     if (STRNCMP ((char *) table_info.pointer, table_signature,
00497               signature_length)) {
00498         /* Invalid RSDT or XSDT signature */
00499 
00500         REPORT_ERROR (("Invalid signature where RSDP indicates %s should be located\n",
00501                   table_signature));
00502 
00503         return (AE_NO_ACPI_TABLES);
00504     }
00505 
00506 
00507     /* Valid RSDT signature, verify the checksum */
00508 
00509     status = acpi_tb_verify_table_checksum (table_info.pointer);
00510 
00511 
00512     /* Convert and/or copy to an XSDT structure */
00513 
00514     status = acpi_tb_convert_to_xsdt (&table_info, number_of_tables);
00515     if (ACPI_FAILURE (status)) {
00516         return (status);
00517     }
00518 
00519     /* Save the table pointers and allocation info */
00520 
00521     status = acpi_tb_init_table_descriptor (ACPI_TABLE_XSDT, &table_info);
00522     if (ACPI_FAILURE (status)) {
00523         return (status);
00524     }
00525 
00526     acpi_gbl_XSDT = (XSDT_DESCRIPTOR *) table_info.pointer;
00527 
00528     return (status);
00529 }
00530 
00531 
00532 /******************************************************************************
00533  *
00534  * FUNCTION:    Acpi_tb_get_table_facs
00535  *
00536  * PARAMETERS:  *Buffer_ptr             - If Buffer_ptr is valid, read data from
00537  *                                          buffer rather than searching memory
00538  *              *Table_info             - Where the table info is returned
00539  *
00540  * RETURN:      Status
00541  *
00542  * DESCRIPTION: Returns a pointer to the FACS as defined in FADT.  This
00543  *              function assumes the global variable FADT has been
00544  *              correctly initialized.  The value of FADT->Firmware_ctrl
00545  *              into a far pointer which is returned.
00546  *
00547  *****************************************************************************/
00548 
00549 ACPI_STATUS
00550 acpi_tb_get_table_facs (
00551     ACPI_TABLE_HEADER       *buffer_ptr,
00552     ACPI_TABLE_DESC         *table_info)
00553 {
00554     void                    *table_ptr = NULL;
00555     u32                     size;
00556     u8                      allocation;
00557     ACPI_STATUS             status = AE_OK;
00558 
00559 
00560     /* Must have a valid FADT pointer */
00561 
00562     if (!acpi_gbl_FADT) {
00563         return (AE_NO_ACPI_TABLES);
00564     }
00565 
00566     size = sizeof (FACS_DESCRIPTOR);
00567     if (buffer_ptr) {
00568         /*
00569          * Getting table from a file -- allocate a buffer and
00570          * read the table.
00571          */
00572         table_ptr = acpi_cm_allocate (size);
00573         if(!table_ptr) {
00574             return (AE_NO_MEMORY);
00575         }
00576 
00577         MEMCPY (table_ptr, buffer_ptr, size);
00578 
00579         /* Save allocation type */
00580 
00581         allocation = ACPI_MEM_ALLOCATED;
00582     }
00583 
00584     else {
00585         /* Just map the physical memory to our address space */
00586 
00587         status = acpi_tb_map_acpi_table ((ACPI_PHYSICAL_ADDRESS) ACPI_GET_ADDRESS (acpi_gbl_FADT->Xfirmware_ctrl),
00588                    &size, &table_ptr);
00589         if (ACPI_FAILURE(status)) {
00590             return (status);
00591         }
00592 
00593         /* Save allocation type */
00594 
00595         allocation = ACPI_MEM_MAPPED;
00596     }
00597 
00598 
00599     /* Return values */
00600 
00601     table_info->pointer     = table_ptr;
00602     table_info->length      = size;
00603     table_info->allocation  = allocation;
00604     table_info->base_pointer = table_ptr;
00605 
00606     return (status);
00607 }
00608 

Generated on Sat May 26 2012 04:25:56 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.