asloffset.c revision 250838
1249109Sjkim/****************************************************************************** 2249109Sjkim * 3249109Sjkim * Module Name: asloffset - Generate a C "offset table" for BIOS use. 4249109Sjkim * 5249109Sjkim *****************************************************************************/ 6249109Sjkim 7249109Sjkim/* 8249109Sjkim * Copyright (C) 2000 - 2013, Intel Corp. 9249109Sjkim * All rights reserved. 10249109Sjkim * 11249109Sjkim * Redistribution and use in source and binary forms, with or without 12249109Sjkim * modification, are permitted provided that the following conditions 13249109Sjkim * are met: 14249109Sjkim * 1. Redistributions of source code must retain the above copyright 15249109Sjkim * notice, this list of conditions, and the following disclaimer, 16249109Sjkim * without modification. 17249109Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18249109Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 19249109Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 20249109Sjkim * including a substantially similar Disclaimer requirement for further 21249109Sjkim * binary redistribution. 22249109Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 23249109Sjkim * of any contributors may be used to endorse or promote products derived 24249109Sjkim * from this software without specific prior written permission. 25249109Sjkim * 26249109Sjkim * Alternatively, this software may be distributed under the terms of the 27249109Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 28249109Sjkim * Software Foundation. 29249109Sjkim * 30249109Sjkim * NO WARRANTY 31249109Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32249109Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33249109Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34249109Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35249109Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36249109Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37249109Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38249109Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39249109Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40249109Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41249109Sjkim * POSSIBILITY OF SUCH DAMAGES. 42249109Sjkim */ 43249109Sjkim 44249112Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h> 45249109Sjkim#include "aslcompiler.y.h" 46249112Sjkim#include <contrib/dev/acpica/include/amlcode.h> 47249112Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 48249109Sjkim 49249109Sjkim 50249109Sjkim#define _COMPONENT ACPI_COMPILER 51249109Sjkim ACPI_MODULE_NAME ("asloffset") 52249109Sjkim 53249109Sjkim 54249109Sjkim/* Local prototypes */ 55249109Sjkim 56249109Sjkimstatic void 57249109SjkimLsEmitOffsetTableEntry ( 58249109Sjkim UINT32 FileId, 59249109Sjkim ACPI_NAMESPACE_NODE *Node, 60249109Sjkim UINT32 Offset, 61249109Sjkim char *OpName, 62249109Sjkim UINT64 Value, 63249109Sjkim UINT8 AmlOpcode); 64249109Sjkim 65249109Sjkim 66249109Sjkim/******************************************************************************* 67249109Sjkim * 68249109Sjkim * FUNCTION: LsAmlOffsetWalk 69249109Sjkim * 70249109Sjkim * PARAMETERS: ASL_WALK_CALLBACK 71249109Sjkim * 72249109Sjkim * RETURN: Status 73249109Sjkim * 74249109Sjkim * DESCRIPTION: Process one node during a offset table file generation. 75249109Sjkim * 76249109Sjkim * Three types of objects are currently emitted to the offset table: 77249109Sjkim * 1) Tagged (named) resource descriptors 78249109Sjkim * 2) Named integer objects with constant integer values 79250838Sjkim * 3) Named package objects 80250838Sjkim * 4) Operation Regions that have constant Offset (address) parameters 81250838Sjkim * 5) Control methods 82249109Sjkim * 83249109Sjkim * The offset table allows the BIOS to dynamically update the values of these 84249109Sjkim * objects at boot time. 85249109Sjkim * 86249109Sjkim ******************************************************************************/ 87249109Sjkim 88249109SjkimACPI_STATUS 89249109SjkimLsAmlOffsetWalk ( 90249109Sjkim ACPI_PARSE_OBJECT *Op, 91249109Sjkim UINT32 Level, 92249109Sjkim void *Context) 93249109Sjkim{ 94249109Sjkim UINT32 FileId = (UINT32) ACPI_TO_INTEGER (Context); 95249109Sjkim ACPI_NAMESPACE_NODE *Node; 96249109Sjkim UINT32 Length; 97249109Sjkim UINT32 OffsetOfOpcode; 98250838Sjkim ACPI_PARSE_OBJECT *NextOp; 99249109Sjkim 100249109Sjkim 101249109Sjkim /* Ignore actual data blocks for resource descriptors */ 102249109Sjkim 103249109Sjkim if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DATA) 104249109Sjkim { 105249109Sjkim return (AE_OK); /* Do NOT update the global AML offset */ 106249109Sjkim } 107249109Sjkim 108249109Sjkim /* We are only interested in named objects (have a namespace node) */ 109249109Sjkim 110249109Sjkim Node = Op->Asl.Node; 111249109Sjkim if (!Node) 112249109Sjkim { 113249109Sjkim Gbl_CurrentAmlOffset += Op->Asl.FinalAmlLength; 114249109Sjkim return (AE_OK); 115249109Sjkim } 116249109Sjkim 117249109Sjkim /* Named resource descriptor (has a descriptor tag) */ 118249109Sjkim 119249109Sjkim if ((Node->Type == ACPI_TYPE_LOCAL_RESOURCE) && 120249109Sjkim (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC)) 121249109Sjkim { 122249109Sjkim LsEmitOffsetTableEntry (FileId, Node, Gbl_CurrentAmlOffset, 123250838Sjkim Op->Asl.ParseOpName, 0, Op->Asl.Extra); 124250838Sjkim Gbl_CurrentAmlOffset += Op->Asl.FinalAmlLength; 125250838Sjkim return (AE_OK); 126249109Sjkim } 127249109Sjkim 128250838Sjkim switch (Op->Asl.AmlOpcode) 129250838Sjkim { 130250838Sjkim case AML_NAME_OP: 131249109Sjkim 132250838Sjkim /* Named object -- Name (NameString, DataRefObject) */ 133250838Sjkim 134249109Sjkim if (!Op->Asl.Child) 135249109Sjkim { 136249109Sjkim FlPrintFile (FileId, "%s NO CHILD!\n", MsgBuffer); 137249109Sjkim return (AE_OK); 138249109Sjkim } 139249109Sjkim 140249109Sjkim Length = Op->Asl.FinalAmlLength; 141249109Sjkim 142249109Sjkim /* Get to the NameSeg/NamePath Op (and length of the name) */ 143249109Sjkim 144249109Sjkim Op = Op->Asl.Child; 145249109Sjkim OffsetOfOpcode = Length + Op->Asl.FinalAmlLength; 146249109Sjkim 147249109Sjkim /* Get actual value associated with the name */ 148249109Sjkim 149249109Sjkim Op = Op->Asl.Next; 150249109Sjkim switch (Op->Asl.AmlOpcode) 151249109Sjkim { 152249109Sjkim /* 153249109Sjkim * We are only interested in integer constants that can be changed 154249109Sjkim * at boot time. Note, the One/Ones/Zero opcodes are considered 155249109Sjkim * non-changeable, so we ignore them here. 156249109Sjkim */ 157249109Sjkim case AML_BYTE_OP: 158249109Sjkim case AML_WORD_OP: 159249109Sjkim case AML_DWORD_OP: 160249109Sjkim case AML_QWORD_OP: 161249109Sjkim 162250838Sjkim /* The +1 is to handle the integer size prefix (opcode) */ 163249109Sjkim 164249109Sjkim LsEmitOffsetTableEntry (FileId, Node, 165249109Sjkim (Gbl_CurrentAmlOffset + OffsetOfOpcode + 1), 166250838Sjkim Op->Asl.ParseOpName, Op->Asl.Value.Integer, 167250838Sjkim (UINT8) Op->Asl.AmlOpcode); 168249109Sjkim break; 169249109Sjkim 170250838Sjkim case AML_PACKAGE_OP: 171250838Sjkim case AML_VAR_PACKAGE_OP: 172250838Sjkim 173250838Sjkim NextOp = Op->Asl.Child; 174250838Sjkim 175250838Sjkim LsEmitOffsetTableEntry (FileId, Node, 176250838Sjkim (Gbl_CurrentAmlOffset + OffsetOfOpcode), 177250838Sjkim Op->Asl.ParseOpName, 178250838Sjkim NextOp->Asl.Value.Integer, 179250838Sjkim (UINT8) Op->Asl.AmlOpcode); 180249109Sjkim break; 181250838Sjkim 182250838Sjkim default: 183250838Sjkim break; 184249109Sjkim } 185249109Sjkim 186249109Sjkim Gbl_CurrentAmlOffset += Length; 187249109Sjkim return (AE_OK); 188249109Sjkim 189250838Sjkim case AML_REGION_OP: 190249109Sjkim 191250838Sjkim /* OperationRegion (NameString, RegionSpace, RegionOffset, RegionLength) */ 192250838Sjkim 193249109Sjkim Length = Op->Asl.FinalAmlLength; 194249109Sjkim 195249109Sjkim /* Get the name/namepath node */ 196249109Sjkim 197250838Sjkim NextOp = Op->Asl.Child; 198250838Sjkim OffsetOfOpcode = Length + NextOp->Asl.FinalAmlLength + 1; 199249109Sjkim 200249109Sjkim /* Get the SpaceId node, then the Offset (address) node */ 201249109Sjkim 202250838Sjkim NextOp = NextOp->Asl.Next; 203250838Sjkim NextOp = NextOp->Asl.Next; 204249109Sjkim 205250838Sjkim switch (NextOp->Asl.AmlOpcode) 206249109Sjkim { 207249109Sjkim /* 208249109Sjkim * We are only interested in integer constants that can be changed 209249109Sjkim * at boot time. Note, the One/Ones/Zero opcodes are considered 210249109Sjkim * non-changeable, so we ignore them here. 211249109Sjkim */ 212249109Sjkim case AML_BYTE_OP: 213249109Sjkim case AML_WORD_OP: 214249109Sjkim case AML_DWORD_OP: 215249109Sjkim case AML_QWORD_OP: 216249109Sjkim 217249109Sjkim LsEmitOffsetTableEntry (FileId, Node, 218249109Sjkim (Gbl_CurrentAmlOffset + OffsetOfOpcode + 1), 219250838Sjkim Op->Asl.ParseOpName, NextOp->Asl.Value.Integer, 220250838Sjkim (UINT8) NextOp->Asl.AmlOpcode); 221249109Sjkim 222249109Sjkim Gbl_CurrentAmlOffset += Length; 223249109Sjkim return (AE_OK); 224249109Sjkim 225249109Sjkim default: 226249109Sjkim break; 227249109Sjkim } 228250838Sjkim break; 229250838Sjkim 230250838Sjkim case AML_METHOD_OP: 231250838Sjkim 232250838Sjkim /* Method (Namepath, ...) */ 233250838Sjkim 234250838Sjkim Length = Op->Asl.FinalAmlLength; 235250838Sjkim 236250838Sjkim /* Get the NameSeg/NamePath Op */ 237250838Sjkim 238250838Sjkim NextOp = Op->Asl.Child; 239250838Sjkim 240250838Sjkim /* Point to the *last* nameseg in the namepath */ 241250838Sjkim 242250838Sjkim OffsetOfOpcode = NextOp->Asl.FinalAmlLength - ACPI_NAME_SIZE; 243250838Sjkim 244250838Sjkim LsEmitOffsetTableEntry (FileId, Node, 245250838Sjkim (Gbl_CurrentAmlOffset + OffsetOfOpcode + Length), 246250838Sjkim Op->Asl.ParseOpName, 247250838Sjkim *((UINT32 *) &NextOp->Asl.Value.Buffer[OffsetOfOpcode]), 248250838Sjkim (UINT8) Op->Asl.AmlOpcode); 249250838Sjkim break; 250250838Sjkim 251250838Sjkim default: 252250838Sjkim break; 253249109Sjkim } 254249109Sjkim 255249109Sjkim Gbl_CurrentAmlOffset += Op->Asl.FinalAmlLength; 256249109Sjkim return (AE_OK); 257249109Sjkim} 258249109Sjkim 259249109Sjkim 260249109Sjkim/******************************************************************************* 261249109Sjkim * 262249109Sjkim * FUNCTION: LsEmitOffsetTableEntry 263249109Sjkim * 264249109Sjkim * PARAMETERS: FileId - ID of current listing file 265249109Sjkim * Node - Namespace node associated with the name 266249109Sjkim * Offset - Offset of the value within the AML table 267249109Sjkim * OpName - Name of the AML opcode 268249109Sjkim * Value - Current value of the AML field 269249109Sjkim * AmlOpcode - Opcode associated with the field 270249109Sjkim * 271249109Sjkim * RETURN: None 272249109Sjkim * 273249109Sjkim * DESCRIPTION: Emit a line of the offset table (-so option) 274249109Sjkim * 275249109Sjkim ******************************************************************************/ 276249109Sjkim 277249109Sjkimstatic void 278249109SjkimLsEmitOffsetTableEntry ( 279249109Sjkim UINT32 FileId, 280249109Sjkim ACPI_NAMESPACE_NODE *Node, 281249109Sjkim UINT32 Offset, 282249109Sjkim char *OpName, 283249109Sjkim UINT64 Value, 284249109Sjkim UINT8 AmlOpcode) 285249109Sjkim{ 286249109Sjkim ACPI_BUFFER TargetPath; 287249109Sjkim ACPI_STATUS Status; 288249109Sjkim 289249109Sjkim 290249109Sjkim /* Get the full pathname to the namespace node */ 291249109Sjkim 292249109Sjkim TargetPath.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 293249109Sjkim Status = AcpiNsHandleToPathname (Node, &TargetPath); 294249109Sjkim if (ACPI_FAILURE (Status)) 295249109Sjkim { 296249109Sjkim return; 297249109Sjkim } 298249109Sjkim 299249109Sjkim /* [1] - Skip the opening backslash for the path */ 300249109Sjkim 301249109Sjkim strcpy (MsgBuffer, "\""); 302249109Sjkim strcat (MsgBuffer, &((char *) TargetPath.Pointer)[1]); 303249109Sjkim strcat (MsgBuffer, "\","); 304249109Sjkim ACPI_FREE (TargetPath.Pointer); 305249109Sjkim 306249109Sjkim /* 307249109Sjkim * Max offset is 4G, constrained by 32-bit ACPI table length. 308249109Sjkim * Max Length for Integers is 8 bytes. 309249109Sjkim */ 310249109Sjkim FlPrintFile (FileId, 311249109Sjkim " {%-29s 0x%8.8X, 0x%2.2X, 0x%8.8X%8.8X}, /* %s */\n", 312249109Sjkim MsgBuffer, Offset, AmlOpcode, ACPI_FORMAT_UINT64 (Value), OpName); 313249109Sjkim} 314249109Sjkim 315249109Sjkim 316249109Sjkim/******************************************************************************* 317249109Sjkim * 318249109Sjkim * FUNCTION: LsDoOffsetTableHeader, LsDoOffsetTableFooter 319249109Sjkim * 320249109Sjkim * PARAMETERS: FileId - ID of current listing file 321249109Sjkim * 322249109Sjkim * RETURN: None 323249109Sjkim * 324249109Sjkim * DESCRIPTION: Header and footer for the offset table file. 325249109Sjkim * 326249109Sjkim ******************************************************************************/ 327249109Sjkim 328249109Sjkimvoid 329249109SjkimLsDoOffsetTableHeader ( 330249109Sjkim UINT32 FileId) 331249109Sjkim{ 332249109Sjkim 333249109Sjkim FlPrintFile (FileId, 334249109Sjkim "#ifndef __AML_OFFSET_TABLE_H\n" 335249109Sjkim "#define __AML_OFFSET_TABLE_H\n\n"); 336249109Sjkim 337249109Sjkim FlPrintFile (FileId, "typedef struct {\n" 338249109Sjkim " char *Pathname;\n" 339249109Sjkim " unsigned long Offset;\n" 340250838Sjkim " unsigned char Opcode;\n" 341250838Sjkim " unsigned long long Value;\n" 342249109Sjkim "} AML_OFFSET_TABLE_ENTRY;\n\n"); 343249109Sjkim 344249109Sjkim FlPrintFile (FileId, 345249109Sjkim "#endif /* __AML_OFFSET_TABLE_H */\n\n"); 346249109Sjkim 347249109Sjkim FlPrintFile (FileId, 348250838Sjkim "/*\n" 349250838Sjkim " * Information about supported object types:\n" 350250838Sjkim " *\n" 351250838Sjkim " * Integers:\n" 352250838Sjkim " * Offset points to the actual integer data\n" 353250838Sjkim " * Opcode is the integer prefix, indicates length of the data\n" 354250838Sjkim " * Value is the existing value in the AML\n" 355250838Sjkim " *\n" 356250838Sjkim " * Packages:\n" 357250838Sjkim " * Offset points to the package opcode\n" 358250838Sjkim " * Opcode is the package or var_package opcode\n" 359250838Sjkim " * Value is the package element cound\n" 360250838Sjkim " *\n" 361250838Sjkim " * Operation Regions:\n" 362250838Sjkim " * Offset points to the region address data\n" 363250838Sjkim " * Opcode is the address integer prefix, indicates length of the data\n" 364250838Sjkim " * Value is the existing address value in the AML\n" 365250838Sjkim " *\n" 366250838Sjkim " * Control Methods:\n" 367250838Sjkim " * Offset points to the first byte of the namepath\n" 368250838Sjkim " *\n" 369250838Sjkim " * Resource Descriptors:\n" 370250838Sjkim " * Offset points to the start of the descriptor\n" 371250838Sjkim " * Opcode is the descriptor type\n" 372250838Sjkim " */\n"); 373250838Sjkim 374250838Sjkim FlPrintFile (FileId, 375249109Sjkim "AML_OFFSET_TABLE_ENTRY %s_%s_OffsetTable[] =\n{\n", 376249109Sjkim Gbl_TableSignature, Gbl_TableId); 377249109Sjkim} 378249109Sjkim 379249109Sjkim 380249109Sjkimvoid 381249109SjkimLsDoOffsetTableFooter ( 382249109Sjkim UINT32 FileId) 383249109Sjkim{ 384249109Sjkim 385249109Sjkim FlPrintFile (FileId, 386249109Sjkim " {0,0,0,0} /* Table terminator */\n};\n\n"); 387249109Sjkim Gbl_CurrentAmlOffset = 0; 388249109Sjkim} 389