1 1.1 christos /****************************************************************************** 2 1.1 christos * 3 1.1 christos * Module Name: osbsdtbl - BSD OSL for obtaining ACPI tables 4 1.1 christos * 5 1.1 christos *****************************************************************************/ 6 1.1 christos 7 1.1.1.13 christos /****************************************************************************** 8 1.1.1.13 christos * 9 1.1.1.13 christos * 1. Copyright Notice 10 1.1.1.13 christos * 11 1.1.1.14 christos * Some or all of this work - Copyright (c) 1999 - 2025, Intel Corp. 12 1.1 christos * All rights reserved. 13 1.1 christos * 14 1.1.1.13 christos * 2. License 15 1.1.1.13 christos * 16 1.1.1.13 christos * 2.1. This is your license from Intel Corp. under its intellectual property 17 1.1.1.13 christos * rights. You may have additional license terms from the party that provided 18 1.1.1.13 christos * you this software, covering your right to use that party's intellectual 19 1.1.1.13 christos * property rights. 20 1.1.1.13 christos * 21 1.1.1.13 christos * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22 1.1.1.13 christos * copy of the source code appearing in this file ("Covered Code") an 23 1.1.1.13 christos * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24 1.1.1.13 christos * base code distributed originally by Intel ("Original Intel Code") to copy, 25 1.1.1.13 christos * make derivatives, distribute, use and display any portion of the Covered 26 1.1.1.13 christos * Code in any form, with the right to sublicense such rights; and 27 1.1.1.13 christos * 28 1.1.1.13 christos * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29 1.1.1.13 christos * license (with the right to sublicense), under only those claims of Intel 30 1.1.1.13 christos * patents that are infringed by the Original Intel Code, to make, use, sell, 31 1.1.1.13 christos * offer to sell, and import the Covered Code and derivative works thereof 32 1.1.1.13 christos * solely to the minimum extent necessary to exercise the above copyright 33 1.1.1.13 christos * license, and in no event shall the patent license extend to any additions 34 1.1.1.13 christos * to or modifications of the Original Intel Code. No other license or right 35 1.1.1.13 christos * is granted directly or by implication, estoppel or otherwise; 36 1.1.1.13 christos * 37 1.1.1.13 christos * The above copyright and patent license is granted only if the following 38 1.1.1.13 christos * conditions are met: 39 1.1.1.13 christos * 40 1.1.1.13 christos * 3. Conditions 41 1.1.1.13 christos * 42 1.1.1.13 christos * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43 1.1.1.13 christos * Redistribution of source code of any substantial portion of the Covered 44 1.1.1.13 christos * Code or modification with rights to further distribute source must include 45 1.1.1.13 christos * the above Copyright Notice, the above License, this list of Conditions, 46 1.1.1.13 christos * and the following Disclaimer and Export Compliance provision. In addition, 47 1.1.1.13 christos * Licensee must cause all Covered Code to which Licensee contributes to 48 1.1.1.13 christos * contain a file documenting the changes Licensee made to create that Covered 49 1.1.1.13 christos * Code and the date of any change. Licensee must include in that file the 50 1.1.1.13 christos * documentation of any changes made by any predecessor Licensee. Licensee 51 1.1.1.13 christos * must include a prominent statement that the modification is derived, 52 1.1.1.13 christos * directly or indirectly, from Original Intel Code. 53 1.1.1.13 christos * 54 1.1.1.13 christos * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55 1.1.1.13 christos * Redistribution of source code of any substantial portion of the Covered 56 1.1.1.13 christos * Code or modification without rights to further distribute source must 57 1.1.1.13 christos * include the following Disclaimer and Export Compliance provision in the 58 1.1.1.13 christos * documentation and/or other materials provided with distribution. In 59 1.1.1.13 christos * addition, Licensee may not authorize further sublicense of source of any 60 1.1.1.13 christos * portion of the Covered Code, and must include terms to the effect that the 61 1.1.1.13 christos * license from Licensee to its licensee is limited to the intellectual 62 1.1.1.13 christos * property embodied in the software Licensee provides to its licensee, and 63 1.1.1.13 christos * not to intellectual property embodied in modifications its licensee may 64 1.1.1.13 christos * make. 65 1.1.1.13 christos * 66 1.1.1.13 christos * 3.3. Redistribution of Executable. Redistribution in executable form of any 67 1.1.1.13 christos * substantial portion of the Covered Code or modification must reproduce the 68 1.1.1.13 christos * above Copyright Notice, and the following Disclaimer and Export Compliance 69 1.1.1.13 christos * provision in the documentation and/or other materials provided with the 70 1.1.1.13 christos * distribution. 71 1.1.1.13 christos * 72 1.1.1.13 christos * 3.4. Intel retains all right, title, and interest in and to the Original 73 1.1.1.13 christos * Intel Code. 74 1.1.1.13 christos * 75 1.1.1.13 christos * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76 1.1.1.13 christos * Intel shall be used in advertising or otherwise to promote the sale, use or 77 1.1.1.13 christos * other dealings in products derived from or relating to the Covered Code 78 1.1.1.13 christos * without prior written authorization from Intel. 79 1.1.1.13 christos * 80 1.1.1.13 christos * 4. Disclaimer and Export Compliance 81 1.1.1.13 christos * 82 1.1.1.13 christos * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83 1.1.1.13 christos * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84 1.1.1.13 christos * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85 1.1.1.13 christos * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86 1.1.1.13 christos * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87 1.1.1.13 christos * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88 1.1.1.13 christos * PARTICULAR PURPOSE. 89 1.1.1.13 christos * 90 1.1.1.13 christos * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91 1.1.1.13 christos * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92 1.1.1.13 christos * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93 1.1.1.13 christos * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94 1.1.1.13 christos * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95 1.1.1.13 christos * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96 1.1.1.13 christos * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97 1.1.1.13 christos * LIMITED REMEDY. 98 1.1.1.13 christos * 99 1.1.1.13 christos * 4.3. Licensee shall not export, either directly or indirectly, any of this 100 1.1.1.13 christos * software or system incorporating such software without first obtaining any 101 1.1.1.13 christos * required license or other approval from the U. S. Department of Commerce or 102 1.1.1.13 christos * any other agency or department of the United States Government. In the 103 1.1.1.13 christos * event Licensee exports any such software from the United States or 104 1.1.1.13 christos * re-exports any such software from a foreign destination, Licensee shall 105 1.1.1.13 christos * ensure that the distribution and export/re-export of the software is in 106 1.1.1.13 christos * compliance with all laws, regulations, orders, or other restrictions of the 107 1.1.1.13 christos * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108 1.1.1.13 christos * any of its subsidiaries will export/re-export any technical data, process, 109 1.1.1.13 christos * software, or service, directly or indirectly, to any country for which the 110 1.1.1.13 christos * United States government or any agency thereof requires an export license, 111 1.1.1.13 christos * other governmental approval, or letter of assurance, without first obtaining 112 1.1.1.13 christos * such license, approval or letter. 113 1.1.1.13 christos * 114 1.1.1.13 christos ***************************************************************************** 115 1.1.1.13 christos * 116 1.1.1.13 christos * Alternatively, you may choose to be licensed under the terms of the 117 1.1.1.13 christos * following license: 118 1.1.1.13 christos * 119 1.1 christos * Redistribution and use in source and binary forms, with or without 120 1.1 christos * modification, are permitted provided that the following conditions 121 1.1 christos * are met: 122 1.1 christos * 1. Redistributions of source code must retain the above copyright 123 1.1 christos * notice, this list of conditions, and the following disclaimer, 124 1.1 christos * without modification. 125 1.1 christos * 2. Redistributions in binary form must reproduce at minimum a disclaimer 126 1.1 christos * substantially similar to the "NO WARRANTY" disclaimer below 127 1.1 christos * ("Disclaimer") and any redistribution must be conditioned upon 128 1.1 christos * including a substantially similar Disclaimer requirement for further 129 1.1 christos * binary redistribution. 130 1.1 christos * 3. Neither the names of the above-listed copyright holders nor the names 131 1.1 christos * of any contributors may be used to endorse or promote products derived 132 1.1 christos * from this software without specific prior written permission. 133 1.1 christos * 134 1.1 christos * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 135 1.1 christos * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 136 1.1.1.10 christos * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 137 1.1 christos * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 138 1.1.1.13 christos * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 139 1.1.1.13 christos * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 140 1.1.1.13 christos * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 141 1.1.1.13 christos * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 142 1.1.1.13 christos * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 143 1.1.1.13 christos * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 144 1.1.1.13 christos * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 145 1.1.1.13 christos * 146 1.1.1.13 christos * Alternatively, you may choose to be licensed under the terms of the 147 1.1.1.13 christos * GNU General Public License ("GPL") version 2 as published by the Free 148 1.1.1.13 christos * Software Foundation. 149 1.1.1.13 christos * 150 1.1.1.13 christos *****************************************************************************/ 151 1.1 christos 152 1.1 christos #include "acpidump.h" 153 1.1 christos 154 1.1.1.5 christos #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined (__DragonFly__) 155 1.1 christos #include <kenv.h> 156 1.1 christos #endif 157 1.1 christos #include <unistd.h> 158 1.1 christos #include <sys/param.h> 159 1.1 christos #include <sys/sysctl.h> 160 1.1 christos 161 1.1 christos 162 1.1 christos #define _COMPONENT ACPI_OS_SERVICES 163 1.1 christos ACPI_MODULE_NAME ("osbsdtbl") 164 1.1 christos 165 1.1 christos 166 1.1 christos /* Local prototypes */ 167 1.1 christos 168 1.1 christos static ACPI_STATUS 169 1.1 christos OslTableInitialize ( 170 1.1 christos void); 171 1.1 christos 172 1.1 christos static ACPI_STATUS 173 1.1 christos OslMapTable ( 174 1.1 christos ACPI_SIZE Address, 175 1.1 christos char *Signature, 176 1.1 christos ACPI_TABLE_HEADER **Table); 177 1.1 christos 178 1.1 christos static ACPI_STATUS 179 1.1 christos OslAddTablesToList ( 180 1.1 christos void); 181 1.1 christos 182 1.1 christos static ACPI_STATUS 183 1.1 christos OslGetTableViaRoot ( 184 1.1 christos char *Signature, 185 1.1 christos UINT32 Instance, 186 1.1 christos ACPI_TABLE_HEADER **Table, 187 1.1 christos ACPI_PHYSICAL_ADDRESS *Address); 188 1.1 christos 189 1.1 christos 190 1.1 christos /* Hints for RSDP */ 191 1.1.1.2 christos #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) 192 1.1 christos #define SYSTEM_KENV "hint.acpi.0.rsdp" 193 1.1 christos #define SYSTEM_SYSCTL "machdep.acpi_root" 194 1.1 christos #elif defined(__NetBSD__) 195 1.1 christos #define SYSTEM_SYSCTL "hw.acpi.root" 196 1.1 christos #endif 197 1.1 christos 198 1.1 christos /* Initialization flags */ 199 1.1 christos 200 1.1 christos UINT8 Gbl_TableListInitialized = FALSE; 201 1.1 christos UINT8 Gbl_MainTableObtained = FALSE; 202 1.1 christos 203 1.1 christos /* Local copies of main ACPI tables */ 204 1.1 christos 205 1.1 christos ACPI_TABLE_RSDP Gbl_Rsdp; 206 1.1 christos ACPI_TABLE_FADT *Gbl_Fadt; 207 1.1 christos ACPI_TABLE_RSDT *Gbl_Rsdt; 208 1.1 christos ACPI_TABLE_XSDT *Gbl_Xsdt; 209 1.1 christos 210 1.1 christos /* Fadt address */ 211 1.1 christos 212 1.1 christos ACPI_PHYSICAL_ADDRESS Gbl_FadtAddress; 213 1.1 christos 214 1.1 christos /* Revision of RSD PTR */ 215 1.1 christos 216 1.1 christos UINT8 Gbl_Revision; 217 1.1 christos 218 1.1 christos /* List of information about obtained ACPI tables */ 219 1.1 christos 220 1.1 christos typedef struct table_info 221 1.1 christos { 222 1.1 christos struct table_info *Next; 223 1.1 christos char Signature[4]; 224 1.1 christos UINT32 Instance; 225 1.1 christos ACPI_PHYSICAL_ADDRESS Address; 226 1.1 christos 227 1.1 christos } OSL_TABLE_INFO; 228 1.1 christos 229 1.1 christos OSL_TABLE_INFO *Gbl_TableListHead = NULL; 230 1.1 christos 231 1.1 christos 232 1.1 christos /****************************************************************************** 233 1.1 christos * 234 1.1 christos * FUNCTION: AcpiOsGetTableByAddress 235 1.1 christos * 236 1.1 christos * PARAMETERS: Address - Physical address of the ACPI table 237 1.1 christos * Table - Where a pointer to the table is returned 238 1.1 christos * 239 1.1 christos * RETURN: Status; Table buffer is returned if AE_OK. 240 1.1 christos * AE_NOT_FOUND: A valid table was not found at the address 241 1.1 christos * 242 1.1 christos * DESCRIPTION: Get an ACPI table via a physical memory address. 243 1.1 christos * 244 1.1 christos *****************************************************************************/ 245 1.1 christos 246 1.1 christos ACPI_STATUS 247 1.1 christos AcpiOsGetTableByAddress ( 248 1.1 christos ACPI_PHYSICAL_ADDRESS Address, 249 1.1 christos ACPI_TABLE_HEADER **Table) 250 1.1 christos { 251 1.1 christos ACPI_TABLE_HEADER *MappedTable; 252 1.1 christos ACPI_TABLE_HEADER *LocalTable; 253 1.1 christos ACPI_STATUS Status; 254 1.1 christos 255 1.1 christos 256 1.1 christos /* Validate the input physical address to avoid program crash */ 257 1.1 christos 258 1.1 christos if (Address < ACPI_HI_RSDP_WINDOW_BASE) 259 1.1 christos { 260 1.1 christos fprintf (stderr, "Invalid table address: 0x%8.8X%8.8X\n", 261 1.1 christos ACPI_FORMAT_UINT64 (Address)); 262 1.1 christos return (AE_BAD_ADDRESS); 263 1.1 christos } 264 1.1 christos 265 1.1 christos /* Map the table and validate it */ 266 1.1 christos 267 1.1 christos Status = OslMapTable (Address, NULL, &MappedTable); 268 1.1 christos if (ACPI_FAILURE (Status)) 269 1.1 christos { 270 1.1 christos return (Status); 271 1.1 christos } 272 1.1 christos 273 1.1 christos /* Copy table to local buffer and return it */ 274 1.1 christos 275 1.1 christos LocalTable = calloc (1, MappedTable->Length); 276 1.1 christos if (!LocalTable) 277 1.1 christos { 278 1.1 christos AcpiOsUnmapMemory (MappedTable, MappedTable->Length); 279 1.1 christos return (AE_NO_MEMORY); 280 1.1 christos } 281 1.1 christos 282 1.1.1.2 christos memcpy (LocalTable, MappedTable, MappedTable->Length); 283 1.1 christos AcpiOsUnmapMemory (MappedTable, MappedTable->Length); 284 1.1 christos 285 1.1 christos *Table = LocalTable; 286 1.1 christos return (AE_OK); 287 1.1 christos } 288 1.1 christos 289 1.1 christos 290 1.1 christos /****************************************************************************** 291 1.1 christos * 292 1.1 christos * FUNCTION: AcpiOsGetTableByName 293 1.1 christos * 294 1.1 christos * PARAMETERS: Signature - ACPI Signature for desired table. Must be 295 1.1 christos * a null terminated 4-character string. 296 1.1 christos * Instance - Multiple table support for SSDT/UEFI (0...n) 297 1.1 christos * Must be 0 for other tables. 298 1.1 christos * Table - Where a pointer to the table is returned 299 1.1 christos * Address - Where the table physical address is returned 300 1.1 christos * 301 1.1 christos * RETURN: Status; Table buffer and physical address returned if AE_OK. 302 1.1 christos * AE_LIMIT: Instance is beyond valid limit 303 1.1 christos * AE_NOT_FOUND: A table with the signature was not found 304 1.1 christos * 305 1.1 christos * NOTE: Assumes the input signature is uppercase. 306 1.1 christos * 307 1.1 christos *****************************************************************************/ 308 1.1 christos 309 1.1 christos ACPI_STATUS 310 1.1 christos AcpiOsGetTableByName ( 311 1.1 christos char *Signature, 312 1.1 christos UINT32 Instance, 313 1.1 christos ACPI_TABLE_HEADER **Table, 314 1.1 christos ACPI_PHYSICAL_ADDRESS *Address) 315 1.1 christos { 316 1.1 christos ACPI_STATUS Status; 317 1.1 christos 318 1.1 christos 319 1.1 christos /* Instance is only valid for SSDT/UEFI tables */ 320 1.1 christos 321 1.1 christos if (Instance && 322 1.1.1.8 christos !ACPI_COMPARE_NAMESEG (Signature, ACPI_SIG_SSDT) && 323 1.1.1.8 christos !ACPI_COMPARE_NAMESEG (Signature, ACPI_SIG_UEFI)) 324 1.1 christos { 325 1.1 christos return (AE_LIMIT); 326 1.1 christos } 327 1.1 christos 328 1.1 christos /* Initialize main tables */ 329 1.1 christos 330 1.1 christos Status = OslTableInitialize (); 331 1.1 christos if (ACPI_FAILURE (Status)) 332 1.1 christos { 333 1.1 christos return (Status); 334 1.1 christos } 335 1.1 christos 336 1.1 christos /* 337 1.1 christos * If one of the main ACPI tables was requested (RSDT/XSDT/FADT), 338 1.1 christos * simply return it immediately. 339 1.1 christos */ 340 1.1.1.8 christos if (ACPI_COMPARE_NAMESEG (Signature, ACPI_SIG_XSDT)) 341 1.1 christos { 342 1.1 christos if (!Gbl_Revision) 343 1.1 christos { 344 1.1 christos return (AE_NOT_FOUND); 345 1.1 christos } 346 1.1 christos 347 1.1 christos *Address = Gbl_Rsdp.XsdtPhysicalAddress; 348 1.1 christos *Table = (ACPI_TABLE_HEADER *) Gbl_Xsdt; 349 1.1 christos return (AE_OK); 350 1.1 christos } 351 1.1 christos 352 1.1.1.8 christos if (ACPI_COMPARE_NAMESEG (Signature, ACPI_SIG_RSDT)) 353 1.1 christos { 354 1.1 christos if (!Gbl_Rsdp.RsdtPhysicalAddress) 355 1.1 christos { 356 1.1 christos return (AE_NOT_FOUND); 357 1.1 christos } 358 1.1 christos 359 1.1 christos *Address = Gbl_Rsdp.RsdtPhysicalAddress; 360 1.1 christos *Table = (ACPI_TABLE_HEADER *) Gbl_Rsdt; 361 1.1 christos return (AE_OK); 362 1.1 christos } 363 1.1 christos 364 1.1.1.8 christos if (ACPI_COMPARE_NAMESEG (Signature, ACPI_SIG_FADT)) 365 1.1 christos { 366 1.1 christos *Address = Gbl_FadtAddress; 367 1.1 christos *Table = (ACPI_TABLE_HEADER *) Gbl_Fadt; 368 1.1 christos return (AE_OK); 369 1.1 christos } 370 1.1 christos 371 1.1 christos /* Not a main ACPI table, attempt to extract it from the RSDT/XSDT */ 372 1.1 christos 373 1.1 christos Status = OslGetTableViaRoot (Signature, Instance, Table, Address); 374 1.1 christos if (ACPI_FAILURE (Status)) 375 1.1 christos { 376 1.1 christos return (Status); 377 1.1 christos } 378 1.1 christos 379 1.1 christos return (AE_OK); 380 1.1 christos } 381 1.1 christos 382 1.1 christos 383 1.1 christos /****************************************************************************** 384 1.1 christos * 385 1.1 christos * FUNCTION: AcpiOsGetTableByIndex 386 1.1 christos * 387 1.1 christos * PARAMETERS: Index - Which table to get 388 1.1 christos * Table - Where a pointer to the table is returned 389 1.1 christos * Instance - Where a pointer to the table instance no. is 390 1.1 christos * returned 391 1.1 christos * Address - Where the table physical address is returned 392 1.1 christos * 393 1.1 christos * RETURN: Status; Table buffer and physical address returned if AE_OK. 394 1.1 christos * AE_LIMIT: Index is beyond valid limit 395 1.1 christos * 396 1.1 christos * DESCRIPTION: Get an ACPI table via an index value (0 through n). Returns 397 1.1 christos * AE_LIMIT when an invalid index is reached. Index is not 398 1.1 christos * necessarily an index into the RSDT/XSDT. 399 1.1 christos * 400 1.1 christos *****************************************************************************/ 401 1.1 christos 402 1.1 christos ACPI_STATUS 403 1.1 christos AcpiOsGetTableByIndex ( 404 1.1 christos UINT32 Index, 405 1.1 christos ACPI_TABLE_HEADER **Table, 406 1.1 christos UINT32 *Instance, 407 1.1 christos ACPI_PHYSICAL_ADDRESS *Address) 408 1.1 christos { 409 1.1 christos OSL_TABLE_INFO *Info; 410 1.1 christos ACPI_STATUS Status; 411 1.1 christos UINT32 i; 412 1.1 christos 413 1.1 christos 414 1.1 christos /* Initialize main tables */ 415 1.1 christos 416 1.1 christos Status = OslTableInitialize (); 417 1.1 christos if (ACPI_FAILURE (Status)) 418 1.1 christos { 419 1.1 christos return (Status); 420 1.1 christos } 421 1.1 christos 422 1.1 christos /* Add all tables to list */ 423 1.1 christos 424 1.1 christos Status = OslAddTablesToList (); 425 1.1 christos if (ACPI_FAILURE (Status)) 426 1.1 christos { 427 1.1 christos return (Status); 428 1.1 christos } 429 1.1 christos 430 1.1 christos /* Validate Index */ 431 1.1 christos 432 1.1 christos if (Index >= Gbl_TableListHead->Instance) 433 1.1 christos { 434 1.1 christos return (AE_LIMIT); 435 1.1 christos } 436 1.1 christos 437 1.1 christos /* Point to the table list entry specified by the Index argument */ 438 1.1 christos 439 1.1 christos Info = Gbl_TableListHead; 440 1.1 christos for (i = 0; i <= Index; i++) 441 1.1 christos { 442 1.1 christos Info = Info->Next; 443 1.1 christos } 444 1.1 christos 445 1.1 christos /* Now we can just get the table via the address or name */ 446 1.1 christos 447 1.1 christos if (Info->Address) 448 1.1 christos { 449 1.1 christos Status = AcpiOsGetTableByAddress (Info->Address, Table); 450 1.1 christos if (ACPI_SUCCESS (Status)) 451 1.1 christos { 452 1.1 christos *Address = Info->Address; 453 1.1 christos } 454 1.1 christos } 455 1.1 christos else 456 1.1 christos { 457 1.1 christos Status = AcpiOsGetTableByName (Info->Signature, Info->Instance, 458 1.1 christos Table, Address); 459 1.1 christos } 460 1.1 christos 461 1.1 christos if (ACPI_SUCCESS (Status)) 462 1.1 christos { 463 1.1 christos *Instance = Info->Instance; 464 1.1 christos } 465 1.1 christos return (Status); 466 1.1 christos } 467 1.1 christos 468 1.1 christos 469 1.1 christos /****************************************************************************** 470 1.1 christos * 471 1.1 christos * FUNCTION: OslTableInitialize 472 1.1 christos * 473 1.1 christos * PARAMETERS: None 474 1.1 christos * 475 1.1 christos * RETURN: Status 476 1.1 christos * 477 1.1 christos * DESCRIPTION: Initialize ACPI table data. Get and store main ACPI tables to 478 1.1 christos * local variables. Main ACPI tables include RSDP, FADT, RSDT, 479 1.1 christos * and/or XSDT. 480 1.1 christos * 481 1.1 christos *****************************************************************************/ 482 1.1 christos 483 1.1 christos static ACPI_STATUS 484 1.1 christos OslTableInitialize ( 485 1.1 christos void) 486 1.1 christos { 487 1.1.1.5 christos #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) 488 1.1 christos char Buffer[32]; 489 1.1 christos #endif 490 1.1 christos ACPI_TABLE_HEADER *MappedTable; 491 1.1 christos UINT8 *TableAddress; 492 1.1 christos UINT8 *RsdpAddress; 493 1.1 christos ACPI_PHYSICAL_ADDRESS RsdpBase; 494 1.1 christos ACPI_SIZE RsdpSize; 495 1.1 christos ACPI_STATUS Status; 496 1.1 christos u_long Address = 0; 497 1.1.1.4 christos #if defined(SYSTEM_SYSCTL) 498 1.1 christos size_t Length = sizeof (Address); 499 1.1.1.4 christos #endif 500 1.1 christos 501 1.1 christos 502 1.1 christos /* Get main ACPI tables from memory on first invocation of this function */ 503 1.1 christos 504 1.1 christos if (Gbl_MainTableObtained) 505 1.1 christos { 506 1.1 christos return (AE_OK); 507 1.1 christos } 508 1.1 christos 509 1.1 christos /* Attempt to use kenv or sysctl to find RSD PTR record. */ 510 1.1 christos 511 1.1 christos if (Gbl_RsdpBase) 512 1.1 christos { 513 1.1 christos Address = Gbl_RsdpBase; 514 1.1 christos } 515 1.1.1.5 christos #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined (__DragonFly__) 516 1.1 christos else if (kenv (KENV_GET, SYSTEM_KENV, Buffer, sizeof (Buffer)) > 0) 517 1.1 christos { 518 1.1.1.2 christos Address = strtoul (Buffer, NULL, 0); 519 1.1 christos } 520 1.1 christos #endif 521 1.1.1.4 christos #if defined(SYSTEM_SYSCTL) 522 1.1 christos if (!Address) 523 1.1 christos { 524 1.1 christos if (sysctlbyname (SYSTEM_SYSCTL, &Address, &Length, NULL, 0) != 0) 525 1.1 christos { 526 1.1 christos Address = 0; 527 1.1 christos } 528 1.1 christos } 529 1.1.1.4 christos #endif 530 1.1 christos if (Address) 531 1.1 christos { 532 1.1 christos RsdpBase = Address; 533 1.1 christos RsdpSize = sizeof (Gbl_Rsdp); 534 1.1 christos } 535 1.1 christos else 536 1.1 christos { 537 1.1 christos RsdpBase = ACPI_HI_RSDP_WINDOW_BASE; 538 1.1 christos RsdpSize = ACPI_HI_RSDP_WINDOW_SIZE; 539 1.1 christos } 540 1.1 christos 541 1.1 christos /* Get RSDP from memory */ 542 1.1 christos 543 1.1 christos RsdpAddress = AcpiOsMapMemory (RsdpBase, RsdpSize); 544 1.1 christos if (!RsdpAddress) 545 1.1 christos { 546 1.1 christos return (AE_BAD_ADDRESS); 547 1.1 christos } 548 1.1 christos 549 1.1 christos /* Search low memory for the RSDP */ 550 1.1 christos 551 1.1 christos TableAddress = AcpiTbScanMemoryForRsdp (RsdpAddress, RsdpSize); 552 1.1 christos if (!TableAddress) 553 1.1 christos { 554 1.1 christos AcpiOsUnmapMemory (RsdpAddress, RsdpSize); 555 1.1 christos return (AE_ERROR); 556 1.1 christos } 557 1.1 christos 558 1.1.1.2 christos memcpy (&Gbl_Rsdp, TableAddress, sizeof (Gbl_Rsdp)); 559 1.1 christos AcpiOsUnmapMemory (RsdpAddress, RsdpSize); 560 1.1 christos 561 1.1 christos /* Get XSDT from memory */ 562 1.1 christos 563 1.1 christos if (Gbl_Rsdp.Revision) 564 1.1 christos { 565 1.1 christos Status = OslMapTable (Gbl_Rsdp.XsdtPhysicalAddress, 566 1.1 christos ACPI_SIG_XSDT, &MappedTable); 567 1.1 christos if (ACPI_FAILURE (Status)) 568 1.1 christos { 569 1.1 christos return (Status); 570 1.1 christos } 571 1.1 christos 572 1.1 christos Gbl_Revision = 2; 573 1.1 christos Gbl_Xsdt = calloc (1, MappedTable->Length); 574 1.1 christos if (!Gbl_Xsdt) 575 1.1 christos { 576 1.1 christos fprintf (stderr, 577 1.1 christos "XSDT: Could not allocate buffer for table of length %X\n", 578 1.1 christos MappedTable->Length); 579 1.1 christos AcpiOsUnmapMemory (MappedTable, MappedTable->Length); 580 1.1 christos return (AE_NO_MEMORY); 581 1.1 christos } 582 1.1 christos 583 1.1.1.2 christos memcpy (Gbl_Xsdt, MappedTable, MappedTable->Length); 584 1.1 christos AcpiOsUnmapMemory (MappedTable, MappedTable->Length); 585 1.1 christos } 586 1.1 christos 587 1.1 christos /* Get RSDT from memory */ 588 1.1 christos 589 1.1 christos if (Gbl_Rsdp.RsdtPhysicalAddress) 590 1.1 christos { 591 1.1 christos Status = OslMapTable (Gbl_Rsdp.RsdtPhysicalAddress, 592 1.1 christos ACPI_SIG_RSDT, &MappedTable); 593 1.1 christos if (ACPI_FAILURE (Status)) 594 1.1 christos { 595 1.1 christos return (Status); 596 1.1 christos } 597 1.1 christos 598 1.1 christos Gbl_Rsdt = calloc (1, MappedTable->Length); 599 1.1 christos if (!Gbl_Rsdt) 600 1.1 christos { 601 1.1 christos fprintf (stderr, 602 1.1 christos "RSDT: Could not allocate buffer for table of length %X\n", 603 1.1 christos MappedTable->Length); 604 1.1 christos AcpiOsUnmapMemory (MappedTable, MappedTable->Length); 605 1.1 christos return (AE_NO_MEMORY); 606 1.1 christos } 607 1.1 christos 608 1.1.1.2 christos memcpy (Gbl_Rsdt, MappedTable, MappedTable->Length); 609 1.1 christos AcpiOsUnmapMemory (MappedTable, MappedTable->Length); 610 1.1 christos } 611 1.1 christos 612 1.1 christos /* Get FADT from memory */ 613 1.1 christos 614 1.1 christos if (Gbl_Revision) 615 1.1 christos { 616 1.1 christos Gbl_FadtAddress = Gbl_Xsdt->TableOffsetEntry[0]; 617 1.1 christos } 618 1.1 christos else 619 1.1 christos { 620 1.1 christos Gbl_FadtAddress = Gbl_Rsdt->TableOffsetEntry[0]; 621 1.1 christos } 622 1.1 christos 623 1.1 christos if (!Gbl_FadtAddress) 624 1.1 christos { 625 1.1 christos fprintf(stderr, "FADT: Table could not be found\n"); 626 1.1 christos return (AE_ERROR); 627 1.1 christos } 628 1.1 christos 629 1.1 christos Status = OslMapTable (Gbl_FadtAddress, ACPI_SIG_FADT, &MappedTable); 630 1.1 christos if (ACPI_FAILURE (Status)) 631 1.1 christos { 632 1.1 christos return (Status); 633 1.1 christos } 634 1.1 christos 635 1.1 christos Gbl_Fadt = calloc (1, MappedTable->Length); 636 1.1 christos if (!Gbl_Fadt) 637 1.1 christos { 638 1.1 christos fprintf (stderr, 639 1.1 christos "FADT: Could not allocate buffer for table of length %X\n", 640 1.1 christos MappedTable->Length); 641 1.1 christos AcpiOsUnmapMemory (MappedTable, MappedTable->Length); 642 1.1 christos return (AE_NO_MEMORY); 643 1.1 christos } 644 1.1 christos 645 1.1.1.2 christos memcpy (Gbl_Fadt, MappedTable, MappedTable->Length); 646 1.1 christos AcpiOsUnmapMemory (MappedTable, MappedTable->Length); 647 1.1 christos Gbl_MainTableObtained = TRUE; 648 1.1 christos return (AE_OK); 649 1.1 christos } 650 1.1 christos 651 1.1 christos 652 1.1 christos /****************************************************************************** 653 1.1 christos * 654 1.1 christos * FUNCTION: OslGetTableViaRoot 655 1.1 christos * 656 1.1 christos * PARAMETERS: Signature - ACPI Signature for common table. Must be 657 1.1 christos * a null terminated 4-character string. 658 1.1 christos * Instance - Multiple table support for SSDT/UEFI (0...n) 659 1.1 christos * Must be 0 for other tables. 660 1.1 christos * Table - Where a pointer to the table is returned 661 1.1 christos * Address - Where the table physical address is returned 662 1.1 christos * 663 1.1 christos * RETURN: Status; Table buffer and physical address returned if AE_OK. 664 1.1 christos * AE_LIMIT: Instance is beyond valid limit 665 1.1 christos * AE_NOT_FOUND: A table with the signature was not found 666 1.1 christos * 667 1.1 christos * DESCRIPTION: Get an ACPI table via the root table (RSDT/XSDT) 668 1.1 christos * 669 1.1 christos * NOTE: Assumes the input signature is uppercase. 670 1.1 christos * 671 1.1 christos *****************************************************************************/ 672 1.1 christos 673 1.1 christos static ACPI_STATUS 674 1.1 christos OslGetTableViaRoot ( 675 1.1 christos char *Signature, 676 1.1 christos UINT32 Instance, 677 1.1 christos ACPI_TABLE_HEADER **Table, 678 1.1 christos ACPI_PHYSICAL_ADDRESS *Address) 679 1.1 christos { 680 1.1 christos ACPI_TABLE_HEADER *LocalTable = NULL; 681 1.1 christos ACPI_TABLE_HEADER *MappedTable = NULL; 682 1.1 christos UINT8 NumberOfTables; 683 1.1 christos UINT32 CurrentInstance = 0; 684 1.1 christos ACPI_PHYSICAL_ADDRESS TableAddress = 0; 685 1.1 christos ACPI_STATUS Status; 686 1.1 christos UINT32 i; 687 1.1 christos 688 1.1 christos 689 1.1 christos /* DSDT and FACS address must be extracted from the FADT */ 690 1.1 christos 691 1.1.1.8 christos if (ACPI_COMPARE_NAMESEG (Signature, ACPI_SIG_DSDT) || 692 1.1.1.8 christos ACPI_COMPARE_NAMESEG (Signature, ACPI_SIG_FACS)) 693 1.1 christos { 694 1.1 christos /* 695 1.1 christos * Get the appropriate address, either 32-bit or 64-bit. Be very 696 1.1 christos * careful about the FADT length and validate table addresses. 697 1.1 christos * Note: The 64-bit addresses have priority. 698 1.1 christos */ 699 1.1.1.8 christos if (ACPI_COMPARE_NAMESEG (Signature, ACPI_SIG_DSDT)) 700 1.1 christos { 701 1.1 christos if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_XDSDT) && 702 1.1 christos Gbl_Fadt->XDsdt) 703 1.1 christos { 704 1.1 christos TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->XDsdt; 705 1.1 christos } 706 1.1 christos else if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_DSDT) && 707 1.1 christos Gbl_Fadt->Dsdt) 708 1.1 christos { 709 1.1 christos TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->Dsdt; 710 1.1 christos } 711 1.1 christos } 712 1.1 christos else /* FACS */ 713 1.1 christos { 714 1.1 christos if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_XFACS) && 715 1.1 christos Gbl_Fadt->XFacs) 716 1.1 christos { 717 1.1 christos TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->XFacs; 718 1.1 christos } 719 1.1 christos else if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_FACS) && 720 1.1 christos Gbl_Fadt->Facs) 721 1.1 christos { 722 1.1 christos TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->Facs; 723 1.1 christos } 724 1.1 christos } 725 1.1 christos } 726 1.1 christos else /* Case for a normal ACPI table */ 727 1.1 christos { 728 1.1 christos if (Gbl_Revision) 729 1.1 christos { 730 1.1 christos NumberOfTables = 731 1.1 christos (Gbl_Xsdt->Header.Length - sizeof (Gbl_Xsdt->Header)) 732 1.1 christos / sizeof (Gbl_Xsdt->TableOffsetEntry[0]); 733 1.1 christos } 734 1.1 christos else /* Use RSDT if XSDT is not available */ 735 1.1 christos { 736 1.1 christos NumberOfTables = 737 1.1 christos (Gbl_Rsdt->Header.Length - sizeof (Gbl_Rsdt->Header)) 738 1.1 christos / sizeof (Gbl_Rsdt->TableOffsetEntry[0]); 739 1.1 christos } 740 1.1 christos 741 1.1 christos /* Search RSDT/XSDT for the requested table */ 742 1.1 christos 743 1.1 christos for (i = 0; i < NumberOfTables; i++) 744 1.1 christos { 745 1.1 christos if (Gbl_Revision) 746 1.1 christos { 747 1.1 christos TableAddress = Gbl_Xsdt->TableOffsetEntry[i]; 748 1.1 christos } 749 1.1 christos else 750 1.1 christos { 751 1.1 christos TableAddress = Gbl_Rsdt->TableOffsetEntry[i]; 752 1.1 christos } 753 1.1 christos 754 1.1 christos MappedTable = AcpiOsMapMemory (TableAddress, sizeof (*MappedTable)); 755 1.1 christos if (!MappedTable) 756 1.1 christos { 757 1.1 christos return (AE_BAD_ADDRESS); 758 1.1 christos } 759 1.1 christos 760 1.1 christos /* Does this table match the requested signature? */ 761 1.1 christos 762 1.1.1.8 christos if (ACPI_COMPARE_NAMESEG (MappedTable->Signature, Signature)) 763 1.1 christos { 764 1.1 christos 765 1.1 christos /* Match table instance (for SSDT/UEFI tables) */ 766 1.1 christos 767 1.1 christos if (CurrentInstance == Instance) 768 1.1 christos { 769 1.1 christos AcpiOsUnmapMemory (MappedTable, sizeof (*MappedTable)); 770 1.1 christos break; 771 1.1 christos } 772 1.1 christos 773 1.1 christos CurrentInstance++; 774 1.1 christos } 775 1.1 christos 776 1.1 christos AcpiOsUnmapMemory (MappedTable, MappedTable->Length); 777 1.1 christos TableAddress = 0; 778 1.1 christos } 779 1.1 christos } 780 1.1 christos 781 1.1 christos if (!TableAddress) 782 1.1 christos { 783 1.1 christos if (CurrentInstance) 784 1.1 christos { 785 1.1 christos return (AE_LIMIT); 786 1.1 christos } 787 1.1 christos return (AE_NOT_FOUND); 788 1.1 christos } 789 1.1 christos 790 1.1 christos /* Now we can get the requested table */ 791 1.1 christos 792 1.1 christos Status = OslMapTable (TableAddress, Signature, &MappedTable); 793 1.1 christos if (ACPI_FAILURE (Status)) 794 1.1 christos { 795 1.1 christos return (Status); 796 1.1 christos } 797 1.1 christos 798 1.1 christos /* Copy table to local buffer and return it */ 799 1.1 christos 800 1.1 christos LocalTable = calloc (1, MappedTable->Length); 801 1.1 christos if (!LocalTable) 802 1.1 christos { 803 1.1 christos AcpiOsUnmapMemory (MappedTable, MappedTable->Length); 804 1.1 christos return (AE_NO_MEMORY); 805 1.1 christos } 806 1.1 christos 807 1.1.1.2 christos memcpy (LocalTable, MappedTable, MappedTable->Length); 808 1.1 christos AcpiOsUnmapMemory (MappedTable, MappedTable->Length); 809 1.1 christos *Table = LocalTable; 810 1.1 christos *Address = TableAddress; 811 1.1 christos return (AE_OK); 812 1.1 christos } 813 1.1 christos 814 1.1 christos 815 1.1 christos /****************************************************************************** 816 1.1 christos * 817 1.1 christos * FUNCTION: OslAddTablesToList 818 1.1 christos * 819 1.1 christos * PARAMETERS: None 820 1.1 christos * 821 1.1 christos * RETURN: Status; Table list is initialized if AE_OK. 822 1.1 christos * 823 1.1 christos * DESCRIPTION: Add ACPI tables to the table list. 824 1.1 christos * 825 1.1 christos *****************************************************************************/ 826 1.1 christos 827 1.1 christos static ACPI_STATUS 828 1.1 christos OslAddTablesToList( 829 1.1 christos void) 830 1.1 christos { 831 1.1 christos ACPI_PHYSICAL_ADDRESS TableAddress; 832 1.1 christos OSL_TABLE_INFO *Info = NULL; 833 1.1 christos OSL_TABLE_INFO *NewInfo; 834 1.1 christos ACPI_TABLE_HEADER *Table; 835 1.1 christos UINT8 Instance; 836 1.1 christos UINT8 NumberOfTables; 837 1.1 christos int i; 838 1.1 christos 839 1.1 christos 840 1.1 christos /* Initialize the table list on first invocation */ 841 1.1 christos 842 1.1 christos if (Gbl_TableListInitialized) 843 1.1 christos { 844 1.1 christos return (AE_OK); 845 1.1 christos } 846 1.1 christos 847 1.1 christos /* Add mandatory tables to global table list first */ 848 1.1 christos 849 1.1 christos for (i = 0; i < 4; i++) 850 1.1 christos { 851 1.1 christos NewInfo = calloc (1, sizeof (*NewInfo)); 852 1.1 christos if (!NewInfo) 853 1.1 christos { 854 1.1 christos return (AE_NO_MEMORY); 855 1.1 christos } 856 1.1 christos 857 1.1 christos switch (i) { 858 1.1 christos case 0: 859 1.1 christos 860 1.1 christos Gbl_TableListHead = Info = NewInfo; 861 1.1 christos continue; 862 1.1 christos 863 1.1 christos case 1: 864 1.1 christos 865 1.1.1.8 christos ACPI_COPY_NAMESEG (NewInfo->Signature, 866 1.1 christos Gbl_Revision ? ACPI_SIG_XSDT : ACPI_SIG_RSDT); 867 1.1 christos break; 868 1.1 christos 869 1.1 christos case 2: 870 1.1 christos 871 1.1.1.8 christos ACPI_COPY_NAMESEG (NewInfo->Signature, ACPI_SIG_FACS); 872 1.1 christos break; 873 1.1 christos 874 1.1 christos default: 875 1.1 christos 876 1.1.1.8 christos ACPI_COPY_NAMESEG (NewInfo->Signature, ACPI_SIG_DSDT); 877 1.1 christos 878 1.1 christos } 879 1.1 christos 880 1.1 christos Info->Next = NewInfo; 881 1.1 christos Info = NewInfo; 882 1.1 christos Gbl_TableListHead->Instance++; 883 1.1 christos } 884 1.1 christos 885 1.1 christos /* Add normal tables from RSDT/XSDT to global list */ 886 1.1 christos 887 1.1 christos if (Gbl_Revision) 888 1.1 christos { 889 1.1 christos NumberOfTables = 890 1.1 christos (Gbl_Xsdt->Header.Length - sizeof (Gbl_Xsdt->Header)) 891 1.1 christos / sizeof (Gbl_Xsdt->TableOffsetEntry[0]); 892 1.1 christos } 893 1.1 christos else 894 1.1 christos { 895 1.1 christos NumberOfTables = 896 1.1 christos (Gbl_Rsdt->Header.Length - sizeof (Gbl_Rsdt->Header)) 897 1.1 christos / sizeof (Gbl_Rsdt->TableOffsetEntry[0]); 898 1.1 christos } 899 1.1 christos 900 1.1 christos for (i = 0; i < NumberOfTables; i++) 901 1.1 christos { 902 1.1 christos if (Gbl_Revision) 903 1.1 christos { 904 1.1 christos TableAddress = Gbl_Xsdt->TableOffsetEntry[i]; 905 1.1 christos } 906 1.1 christos else 907 1.1 christos { 908 1.1 christos TableAddress = Gbl_Rsdt->TableOffsetEntry[i]; 909 1.1 christos } 910 1.1 christos 911 1.1 christos Table = AcpiOsMapMemory (TableAddress, sizeof (*Table)); 912 1.1 christos if (!Table) 913 1.1 christos { 914 1.1 christos return (AE_BAD_ADDRESS); 915 1.1 christos } 916 1.1 christos 917 1.1 christos Instance = 0; 918 1.1 christos NewInfo = Gbl_TableListHead; 919 1.1 christos while (NewInfo->Next != NULL) 920 1.1 christos { 921 1.1 christos NewInfo = NewInfo->Next; 922 1.1.1.8 christos if (ACPI_COMPARE_NAMESEG (Table->Signature, NewInfo->Signature)) 923 1.1 christos { 924 1.1 christos Instance++; 925 1.1 christos } 926 1.1 christos } 927 1.1 christos 928 1.1 christos NewInfo = calloc (1, sizeof (*NewInfo)); 929 1.1 christos if (!NewInfo) 930 1.1 christos { 931 1.1 christos AcpiOsUnmapMemory (Table, sizeof (*Table)); 932 1.1 christos return (AE_NO_MEMORY); 933 1.1 christos } 934 1.1 christos 935 1.1.1.8 christos ACPI_COPY_NAMESEG (NewInfo->Signature, Table->Signature); 936 1.1 christos 937 1.1 christos AcpiOsUnmapMemory (Table, sizeof (*Table)); 938 1.1 christos 939 1.1 christos NewInfo->Instance = Instance; 940 1.1 christos NewInfo->Address = TableAddress; 941 1.1 christos Info->Next = NewInfo; 942 1.1 christos Info = NewInfo; 943 1.1 christos Gbl_TableListHead->Instance++; 944 1.1 christos } 945 1.1 christos 946 1.1 christos Gbl_TableListInitialized = TRUE; 947 1.1 christos return (AE_OK); 948 1.1 christos } 949 1.1 christos 950 1.1 christos 951 1.1 christos /****************************************************************************** 952 1.1 christos * 953 1.1 christos * FUNCTION: OslMapTable 954 1.1 christos * 955 1.1 christos * PARAMETERS: Address - Address of the table in memory 956 1.1 christos * Signature - Optional ACPI Signature for desired table. 957 1.1 christos * Null terminated 4-character string. 958 1.1 christos * Table - Where a pointer to the mapped table is 959 1.1 christos * returned 960 1.1 christos * 961 1.1 christos * RETURN: Status; Mapped table is returned if AE_OK. 962 1.1 christos * 963 1.1 christos * DESCRIPTION: Map entire ACPI table into caller's address space. Also 964 1.1 christos * validates the table and checksum. 965 1.1 christos * 966 1.1 christos *****************************************************************************/ 967 1.1 christos 968 1.1 christos static ACPI_STATUS 969 1.1 christos OslMapTable ( 970 1.1 christos ACPI_SIZE Address, 971 1.1 christos char *Signature, 972 1.1 christos ACPI_TABLE_HEADER **Table) 973 1.1 christos { 974 1.1 christos ACPI_TABLE_HEADER *MappedTable; 975 1.1 christos UINT32 Length; 976 1.1 christos 977 1.1 christos 978 1.1 christos /* Map the header so we can get the table length */ 979 1.1 christos 980 1.1 christos MappedTable = AcpiOsMapMemory (Address, sizeof (*MappedTable)); 981 1.1 christos if (!MappedTable) 982 1.1 christos { 983 1.1 christos return (AE_BAD_ADDRESS); 984 1.1 christos } 985 1.1 christos 986 1.1 christos /* Check if table is valid */ 987 1.1 christos 988 1.1 christos if (!ApIsValidHeader (MappedTable)) 989 1.1 christos { 990 1.1 christos AcpiOsUnmapMemory (MappedTable, sizeof (*MappedTable)); 991 1.1 christos return (AE_BAD_HEADER); 992 1.1 christos } 993 1.1 christos 994 1.1 christos /* If specified, signature must match */ 995 1.1 christos 996 1.1 christos if (Signature && 997 1.1.1.8 christos !ACPI_COMPARE_NAMESEG (Signature, MappedTable->Signature)) 998 1.1 christos { 999 1.1 christos AcpiOsUnmapMemory (MappedTable, sizeof (*MappedTable)); 1000 1.1 christos return (AE_NOT_EXIST); 1001 1.1 christos } 1002 1.1 christos 1003 1.1 christos /* Map the entire table */ 1004 1.1 christos 1005 1.1 christos Length = MappedTable->Length; 1006 1.1 christos AcpiOsUnmapMemory (MappedTable, sizeof (*MappedTable)); 1007 1.1 christos 1008 1.1 christos MappedTable = AcpiOsMapMemory (Address, Length); 1009 1.1 christos if (!MappedTable) 1010 1.1 christos { 1011 1.1 christos return (AE_BAD_ADDRESS); 1012 1.1 christos } 1013 1.1 christos 1014 1.1 christos (void) ApIsValidChecksum (MappedTable); 1015 1.1 christos 1016 1.1 christos *Table = MappedTable; 1017 1.1 christos 1018 1.1 christos return (AE_OK); 1019 1.1 christos } 1020