asloffset.c revision 249109
1139823Simp/****************************************************************************** 21541Srgrimes * 31541Srgrimes * Module Name: asloffset - Generate a C "offset table" for BIOS use. 41541Srgrimes * 51541Srgrimes *****************************************************************************/ 61541Srgrimes 71541Srgrimes/* 81541Srgrimes * Copyright (C) 2000 - 2013, Intel Corp. 91541Srgrimes * All rights reserved. 101541Srgrimes * 111541Srgrimes * Redistribution and use in source and binary forms, with or without 121541Srgrimes * modification, are permitted provided that the following conditions 131541Srgrimes * are met: 141541Srgrimes * 1. Redistributions of source code must retain the above copyright 151541Srgrimes * notice, this list of conditions, and the following disclaimer, 161541Srgrimes * without modification. 171541Srgrimes * 2. Redistributions in binary form must reproduce at minimum a disclaimer 181541Srgrimes * substantially similar to the "NO WARRANTY" disclaimer below 191541Srgrimes * ("Disclaimer") and any redistribution must be conditioned upon 201541Srgrimes * including a substantially similar Disclaimer requirement for further 211541Srgrimes * binary redistribution. 221541Srgrimes * 3. Neither the names of the above-listed copyright holders nor the names 231541Srgrimes * of any contributors may be used to endorse or promote products derived 241541Srgrimes * from this software without specific prior written permission. 251541Srgrimes * 261541Srgrimes * Alternatively, this software may be distributed under the terms of the 271541Srgrimes * GNU General Public License ("GPL") version 2 as published by the Free 281541Srgrimes * Software Foundation. 2910939Swollman * 3050477Speter * NO WARRANTY 311541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 321541Srgrimes * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 332169Spaul * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 342169Spaul * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 352169Spaul * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 367280Swollman * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3784102Sjlemon * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 387280Swollman * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 391541Srgrimes * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 401541Srgrimes * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 4121666Swollman * POSSIBILITY OF SUCH DAMAGES. 421541Srgrimes */ 431541Srgrimes 441541Srgrimes#include "aslcompiler.h" 451541Srgrimes#include "aslcompiler.y.h" 461541Srgrimes#include "amlcode.h" 471541Srgrimes#include "acnamesp.h" 481541Srgrimes 491541Srgrimes 501541Srgrimes#define _COMPONENT ACPI_COMPILER 511541Srgrimes ACPI_MODULE_NAME ("asloffset") 521541Srgrimes 531541Srgrimes 541541Srgrimes/* Local prototypes */ 5584102Sjlemon 5684102Sjlemonstatic void 571541SrgrimesLsEmitOffsetTableEntry ( 581541Srgrimes UINT32 FileId, 591541Srgrimes ACPI_NAMESPACE_NODE *Node, 601541Srgrimes UINT32 Offset, 611541Srgrimes UINT32 Length, 621541Srgrimes char *OpName, 631541Srgrimes UINT64 Value, 641541Srgrimes UINT8 AmlOpcode); 651541Srgrimes 661541Srgrimes 671541Srgrimes/******************************************************************************* 681541Srgrimes * 691541Srgrimes * FUNCTION: LsAmlOffsetWalk 701541Srgrimes * 711541Srgrimes * PARAMETERS: ASL_WALK_CALLBACK 721541Srgrimes * 731541Srgrimes * RETURN: Status 743865Sswallace * 753865Sswallace * DESCRIPTION: Process one node during a offset table file generation. 761541Srgrimes * 771541Srgrimes * Three types of objects are currently emitted to the offset table: 781541Srgrimes * 1) Tagged (named) resource descriptors 791541Srgrimes * 2) Named integer objects with constant integer values 808876Srgrimes * 3) Operation Regions that have constant Offset (address) parameters 8155205Speter * 827090Sbde * The offset table allows the BIOS to dynamically update the values of these 831541Srgrimes * objects at boot time. 84133874Srwatson * 8584102Sjlemon ******************************************************************************/ 8684102Sjlemon 8784102SjlemonACPI_STATUS 8884102SjlemonLsAmlOffsetWalk ( 8984102Sjlemon ACPI_PARSE_OBJECT *Op, 9084102Sjlemon UINT32 Level, 9184102Sjlemon void *Context) 9284102Sjlemon{ 9384102Sjlemon UINT32 FileId = (UINT32) ACPI_TO_INTEGER (Context); 9484102Sjlemon ACPI_NAMESPACE_NODE *Node; 9584102Sjlemon UINT32 Length; 9684102Sjlemon UINT32 OffsetOfOpcode; 9784102Sjlemon ACPI_PARSE_OBJECT *AddressOp; 981541Srgrimes 991541Srgrimes 1001541Srgrimes /* Ignore actual data blocks for resource descriptors */ 1011541Srgrimes 1021541Srgrimes if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DATA) 1031541Srgrimes { 1041541Srgrimes return (AE_OK); /* Do NOT update the global AML offset */ 1051541Srgrimes } 10679821Sru 1071541Srgrimes /* We are only interested in named objects (have a namespace node) */ 10884109Sjlemon 10979821Sru Node = Op->Asl.Node; 11079821Sru if (!Node) 1111541Srgrimes { 1121541Srgrimes Gbl_CurrentAmlOffset += Op->Asl.FinalAmlLength; 1131541Srgrimes return (AE_OK); 1141541Srgrimes } 1151541Srgrimes 1161541Srgrimes /* Named resource descriptor (has a descriptor tag) */ 1171541Srgrimes 1181541Srgrimes if ((Node->Type == ACPI_TYPE_LOCAL_RESOURCE) && 1191541Srgrimes (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC)) 1201541Srgrimes { 1211541Srgrimes LsEmitOffsetTableEntry (FileId, Node, Gbl_CurrentAmlOffset, 12271998Sphk Op->Asl.FinalAmlLength, Op->Asl.ParseOpName, 0, Op->Asl.Extra); 1231541Srgrimes } 12471998Sphk 1251541Srgrimes /* Named object -- Name (NameString, DataRefObject) */ 1261541Srgrimes 1271541Srgrimes else if (Op->Asl.AmlOpcode == AML_NAME_OP) 1281541Srgrimes { 1291541Srgrimes if (!Op->Asl.Child) 1302531Swollman { 1312531Swollman FlPrintFile (FileId, "%s NO CHILD!\n", MsgBuffer); 1322531Swollman return (AE_OK); 1332531Swollman } 1342531Swollman 13514622Sfenner Length = Op->Asl.FinalAmlLength; 13614622Sfenner 13714622Sfenner /* Get to the NameSeg/NamePath Op (and length of the name) */ 138119180Srwatson 1392531Swollman Op = Op->Asl.Child; 1402531Swollman OffsetOfOpcode = Length + Op->Asl.FinalAmlLength; 1412531Swollman 1421541Srgrimes /* Get actual value associated with the name */ 1431541Srgrimes 14421666Swollman Op = Op->Asl.Next; 14521666Swollman switch (Op->Asl.AmlOpcode) 14621666Swollman { 14721666Swollman /* 1481541Srgrimes * We are only interested in integer constants that can be changed 1491541Srgrimes * at boot time. Note, the One/Ones/Zero opcodes are considered 15060938Sjake * non-changeable, so we ignore them here. 15121666Swollman */ 1521541Srgrimes case AML_BYTE_OP: 15321666Swollman case AML_WORD_OP: 1541541Srgrimes case AML_DWORD_OP: 1552531Swollman case AML_QWORD_OP: 1562531Swollman 1571541Srgrimes /* The +1/-1 is to handle the integer size prefix (opcode) */ 1581541Srgrimes 15955205Speter LsEmitOffsetTableEntry (FileId, Node, 16044078Sdfr (Gbl_CurrentAmlOffset + OffsetOfOpcode + 1), 16144078Sdfr (Op->Asl.FinalAmlLength - 1), Op->Asl.ParseOpName, 162136713Sandre Op->Asl.Value.Integer, (UINT8) Op->Asl.AmlOpcode); 16344078Sdfr break; 16444078Sdfr 16544078Sdfr default: 16644078Sdfr break; 16760938Sjake } 16821666Swollman 1691541Srgrimes Gbl_CurrentAmlOffset += Length; 1701541Srgrimes return (AE_OK); 1711541Srgrimes } 1721541Srgrimes 1731541Srgrimes /* OperationRegion (NameString, RegionSpace, RegionOffset, RegionLength) */ 1741541Srgrimes 1751541Srgrimes else if (Op->Asl.AmlOpcode == AML_REGION_OP) 1761541Srgrimes { 1771541Srgrimes Length = Op->Asl.FinalAmlLength; 1781541Srgrimes 17921666Swollman /* Get the name/namepath node */ 1801541Srgrimes 1811541Srgrimes AddressOp = Op->Asl.Child; 1821541Srgrimes OffsetOfOpcode = Length + AddressOp->Asl.FinalAmlLength + 1; 1831541Srgrimes 1841541Srgrimes /* Get the SpaceId node, then the Offset (address) node */ 18520407Swollman 18679821Sru AddressOp = AddressOp->Asl.Next; 1871541Srgrimes AddressOp = AddressOp->Asl.Next; 188148653Srwatson 18972084Sphk switch (AddressOp->Asl.AmlOpcode) 19021666Swollman { 19121929Swollman /* 19221666Swollman * We are only interested in integer constants that can be changed 19321666Swollman * at boot time. Note, the One/Ones/Zero opcodes are considered 19421666Swollman * non-changeable, so we ignore them here. 19521666Swollman */ 196148653Srwatson case AML_BYTE_OP: 19720407Swollman case AML_WORD_OP: 1981541Srgrimes case AML_DWORD_OP: 1991541Srgrimes case AML_QWORD_OP: 2001541Srgrimes 2011541Srgrimes /* The +1/-1 is to handle the integer size prefix (opcode) */ 2021541Srgrimes 2031541Srgrimes LsEmitOffsetTableEntry (FileId, Node, 2041541Srgrimes (Gbl_CurrentAmlOffset + OffsetOfOpcode + 1), 2051541Srgrimes (AddressOp->Asl.FinalAmlLength - 1), Op->Asl.ParseOpName, 2061541Srgrimes AddressOp->Asl.Value.Integer, (UINT8) AddressOp->Asl.AmlOpcode); 2071541Srgrimes 2081541Srgrimes Gbl_CurrentAmlOffset += Length; 20920407Swollman return (AE_OK); 2101541Srgrimes 21171998Sphk default: 21220407Swollman break; 2131541Srgrimes } 2141541Srgrimes } 2151541Srgrimes 2161541Srgrimes Gbl_CurrentAmlOffset += Op->Asl.FinalAmlLength; 21720407Swollman return (AE_OK); 21871998Sphk} 2191541Srgrimes 22020407Swollman 2211541Srgrimes/******************************************************************************* 22236192Sdg * 22392723Salfred * FUNCTION: LsEmitOffsetTableEntry 22492723Salfred * 22592723Salfred * PARAMETERS: FileId - ID of current listing file 22693085Sbde * Node - Namespace node associated with the name 22792723Salfred * Offset - Offset of the value within the AML table 22892723Salfred * Length - Length in bytes of the value 22992723Salfred * OpName - Name of the AML opcode 23092723Salfred * Value - Current value of the AML field 231122702Sandre * AmlOpcode - Opcode associated with the field 2322169Spaul * 23355205Speter * RETURN: None 23410939Swollman * 23552904Sshin * DESCRIPTION: Emit a line of the offset table (-so option) 23652904Sshin * 23752904Sshin ******************************************************************************/ 23810939Swollman 239static void 240LsEmitOffsetTableEntry ( 241 UINT32 FileId, 242 ACPI_NAMESPACE_NODE *Node, 243 UINT32 Offset, 244 UINT32 Length, 245 char *OpName, 246 UINT64 Value, 247 UINT8 AmlOpcode) 248{ 249 ACPI_BUFFER TargetPath; 250 ACPI_STATUS Status; 251 252 253 /* Get the full pathname to the namespace node */ 254 255 TargetPath.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 256 Status = AcpiNsHandleToPathname (Node, &TargetPath); 257 if (ACPI_FAILURE (Status)) 258 { 259 return; 260 } 261 262 /* [1] - Skip the opening backslash for the path */ 263 264 strcpy (MsgBuffer, "\""); 265 strcat (MsgBuffer, &((char *) TargetPath.Pointer)[1]); 266 strcat (MsgBuffer, "\","); 267 ACPI_FREE (TargetPath.Pointer); 268 269 /* 270 * Max offset is 4G, constrained by 32-bit ACPI table length. 271 * Max Length for Integers is 8 bytes. 272 */ 273 FlPrintFile (FileId, 274 " {%-29s 0x%8.8X, 0x%2.2X, 0x%8.8X%8.8X}, /* %s */\n", 275 MsgBuffer, Offset, AmlOpcode, ACPI_FORMAT_UINT64 (Value), OpName); 276} 277 278 279/******************************************************************************* 280 * 281 * FUNCTION: LsDoOffsetTableHeader, LsDoOffsetTableFooter 282 * 283 * PARAMETERS: FileId - ID of current listing file 284 * 285 * RETURN: None 286 * 287 * DESCRIPTION: Header and footer for the offset table file. 288 * 289 ******************************************************************************/ 290 291void 292LsDoOffsetTableHeader ( 293 UINT32 FileId) 294{ 295 296 Gbl_CurrentAmlOffset = 0; 297 298 FlPrintFile (FileId, 299 "#ifndef __AML_OFFSET_TABLE_H\n" 300 "#define __AML_OFFSET_TABLE_H\n\n"); 301 302 FlPrintFile (FileId, "typedef struct {\n" 303 " char *Pathname;\n" 304 " unsigned long Offset;\n" 305 " unsigned char AmlOpcode;\n" 306 " unsigned long long AmlValue;\n" 307 "} AML_OFFSET_TABLE_ENTRY;\n\n"); 308 309 FlPrintFile (FileId, 310 "#endif /* __AML_OFFSET_TABLE_H */\n\n"); 311 312 FlPrintFile (FileId, 313 "AML_OFFSET_TABLE_ENTRY %s_%s_OffsetTable[] =\n{\n", 314 Gbl_TableSignature, Gbl_TableId); 315} 316 317 318void 319LsDoOffsetTableFooter ( 320 UINT32 FileId) 321{ 322 323 FlPrintFile (FileId, 324 " {0,0,0,0} /* Table terminator */\n};\n\n"); 325 Gbl_CurrentAmlOffset = 0; 326} 327