asloffset.c revision 249112
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 UINT32 Length, 62249109Sjkim char *OpName, 63249109Sjkim UINT64 Value, 64249109Sjkim UINT8 AmlOpcode); 65249109Sjkim 66249109Sjkim 67249109Sjkim/******************************************************************************* 68249109Sjkim * 69249109Sjkim * FUNCTION: LsAmlOffsetWalk 70249109Sjkim * 71249109Sjkim * PARAMETERS: ASL_WALK_CALLBACK 72249109Sjkim * 73249109Sjkim * RETURN: Status 74249109Sjkim * 75249109Sjkim * DESCRIPTION: Process one node during a offset table file generation. 76249109Sjkim * 77249109Sjkim * Three types of objects are currently emitted to the offset table: 78249109Sjkim * 1) Tagged (named) resource descriptors 79249109Sjkim * 2) Named integer objects with constant integer values 80249109Sjkim * 3) Operation Regions that have constant Offset (address) parameters 81249109Sjkim * 82249109Sjkim * The offset table allows the BIOS to dynamically update the values of these 83249109Sjkim * objects at boot time. 84249109Sjkim * 85249109Sjkim ******************************************************************************/ 86249109Sjkim 87249109SjkimACPI_STATUS 88249109SjkimLsAmlOffsetWalk ( 89249109Sjkim ACPI_PARSE_OBJECT *Op, 90249109Sjkim UINT32 Level, 91249109Sjkim void *Context) 92249109Sjkim{ 93249109Sjkim UINT32 FileId = (UINT32) ACPI_TO_INTEGER (Context); 94249109Sjkim ACPI_NAMESPACE_NODE *Node; 95249109Sjkim UINT32 Length; 96249109Sjkim UINT32 OffsetOfOpcode; 97249109Sjkim ACPI_PARSE_OBJECT *AddressOp; 98249109Sjkim 99249109Sjkim 100249109Sjkim /* Ignore actual data blocks for resource descriptors */ 101249109Sjkim 102249109Sjkim if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DATA) 103249109Sjkim { 104249109Sjkim return (AE_OK); /* Do NOT update the global AML offset */ 105249109Sjkim } 106249109Sjkim 107249109Sjkim /* We are only interested in named objects (have a namespace node) */ 108249109Sjkim 109249109Sjkim Node = Op->Asl.Node; 110249109Sjkim if (!Node) 111249109Sjkim { 112249109Sjkim Gbl_CurrentAmlOffset += Op->Asl.FinalAmlLength; 113249109Sjkim return (AE_OK); 114249109Sjkim } 115249109Sjkim 116249109Sjkim /* Named resource descriptor (has a descriptor tag) */ 117249109Sjkim 118249109Sjkim if ((Node->Type == ACPI_TYPE_LOCAL_RESOURCE) && 119249109Sjkim (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC)) 120249109Sjkim { 121249109Sjkim LsEmitOffsetTableEntry (FileId, Node, Gbl_CurrentAmlOffset, 122249109Sjkim Op->Asl.FinalAmlLength, Op->Asl.ParseOpName, 0, Op->Asl.Extra); 123249109Sjkim } 124249109Sjkim 125249109Sjkim /* Named object -- Name (NameString, DataRefObject) */ 126249109Sjkim 127249109Sjkim else if (Op->Asl.AmlOpcode == AML_NAME_OP) 128249109Sjkim { 129249109Sjkim if (!Op->Asl.Child) 130249109Sjkim { 131249109Sjkim FlPrintFile (FileId, "%s NO CHILD!\n", MsgBuffer); 132249109Sjkim return (AE_OK); 133249109Sjkim } 134249109Sjkim 135249109Sjkim Length = Op->Asl.FinalAmlLength; 136249109Sjkim 137249109Sjkim /* Get to the NameSeg/NamePath Op (and length of the name) */ 138249109Sjkim 139249109Sjkim Op = Op->Asl.Child; 140249109Sjkim OffsetOfOpcode = Length + Op->Asl.FinalAmlLength; 141249109Sjkim 142249109Sjkim /* Get actual value associated with the name */ 143249109Sjkim 144249109Sjkim Op = Op->Asl.Next; 145249109Sjkim switch (Op->Asl.AmlOpcode) 146249109Sjkim { 147249109Sjkim /* 148249109Sjkim * We are only interested in integer constants that can be changed 149249109Sjkim * at boot time. Note, the One/Ones/Zero opcodes are considered 150249109Sjkim * non-changeable, so we ignore them here. 151249109Sjkim */ 152249109Sjkim case AML_BYTE_OP: 153249109Sjkim case AML_WORD_OP: 154249109Sjkim case AML_DWORD_OP: 155249109Sjkim case AML_QWORD_OP: 156249109Sjkim 157249109Sjkim /* The +1/-1 is to handle the integer size prefix (opcode) */ 158249109Sjkim 159249109Sjkim LsEmitOffsetTableEntry (FileId, Node, 160249109Sjkim (Gbl_CurrentAmlOffset + OffsetOfOpcode + 1), 161249109Sjkim (Op->Asl.FinalAmlLength - 1), Op->Asl.ParseOpName, 162249109Sjkim Op->Asl.Value.Integer, (UINT8) Op->Asl.AmlOpcode); 163249109Sjkim break; 164249109Sjkim 165249109Sjkim default: 166249109Sjkim break; 167249109Sjkim } 168249109Sjkim 169249109Sjkim Gbl_CurrentAmlOffset += Length; 170249109Sjkim return (AE_OK); 171249109Sjkim } 172249109Sjkim 173249109Sjkim /* OperationRegion (NameString, RegionSpace, RegionOffset, RegionLength) */ 174249109Sjkim 175249109Sjkim else if (Op->Asl.AmlOpcode == AML_REGION_OP) 176249109Sjkim { 177249109Sjkim Length = Op->Asl.FinalAmlLength; 178249109Sjkim 179249109Sjkim /* Get the name/namepath node */ 180249109Sjkim 181249109Sjkim AddressOp = Op->Asl.Child; 182249109Sjkim OffsetOfOpcode = Length + AddressOp->Asl.FinalAmlLength + 1; 183249109Sjkim 184249109Sjkim /* Get the SpaceId node, then the Offset (address) node */ 185249109Sjkim 186249109Sjkim AddressOp = AddressOp->Asl.Next; 187249109Sjkim AddressOp = AddressOp->Asl.Next; 188249109Sjkim 189249109Sjkim switch (AddressOp->Asl.AmlOpcode) 190249109Sjkim { 191249109Sjkim /* 192249109Sjkim * We are only interested in integer constants that can be changed 193249109Sjkim * at boot time. Note, the One/Ones/Zero opcodes are considered 194249109Sjkim * non-changeable, so we ignore them here. 195249109Sjkim */ 196249109Sjkim case AML_BYTE_OP: 197249109Sjkim case AML_WORD_OP: 198249109Sjkim case AML_DWORD_OP: 199249109Sjkim case AML_QWORD_OP: 200249109Sjkim 201249109Sjkim /* The +1/-1 is to handle the integer size prefix (opcode) */ 202249109Sjkim 203249109Sjkim LsEmitOffsetTableEntry (FileId, Node, 204249109Sjkim (Gbl_CurrentAmlOffset + OffsetOfOpcode + 1), 205249109Sjkim (AddressOp->Asl.FinalAmlLength - 1), Op->Asl.ParseOpName, 206249109Sjkim AddressOp->Asl.Value.Integer, (UINT8) AddressOp->Asl.AmlOpcode); 207249109Sjkim 208249109Sjkim Gbl_CurrentAmlOffset += Length; 209249109Sjkim return (AE_OK); 210249109Sjkim 211249109Sjkim default: 212249109Sjkim break; 213249109Sjkim } 214249109Sjkim } 215249109Sjkim 216249109Sjkim Gbl_CurrentAmlOffset += Op->Asl.FinalAmlLength; 217249109Sjkim return (AE_OK); 218249109Sjkim} 219249109Sjkim 220249109Sjkim 221249109Sjkim/******************************************************************************* 222249109Sjkim * 223249109Sjkim * FUNCTION: LsEmitOffsetTableEntry 224249109Sjkim * 225249109Sjkim * PARAMETERS: FileId - ID of current listing file 226249109Sjkim * Node - Namespace node associated with the name 227249109Sjkim * Offset - Offset of the value within the AML table 228249109Sjkim * Length - Length in bytes of the value 229249109Sjkim * OpName - Name of the AML opcode 230249109Sjkim * Value - Current value of the AML field 231249109Sjkim * AmlOpcode - Opcode associated with the field 232249109Sjkim * 233249109Sjkim * RETURN: None 234249109Sjkim * 235249109Sjkim * DESCRIPTION: Emit a line of the offset table (-so option) 236249109Sjkim * 237249109Sjkim ******************************************************************************/ 238249109Sjkim 239249109Sjkimstatic void 240249109SjkimLsEmitOffsetTableEntry ( 241249109Sjkim UINT32 FileId, 242249109Sjkim ACPI_NAMESPACE_NODE *Node, 243249109Sjkim UINT32 Offset, 244249109Sjkim UINT32 Length, 245249109Sjkim char *OpName, 246249109Sjkim UINT64 Value, 247249109Sjkim UINT8 AmlOpcode) 248249109Sjkim{ 249249109Sjkim ACPI_BUFFER TargetPath; 250249109Sjkim ACPI_STATUS Status; 251249109Sjkim 252249109Sjkim 253249109Sjkim /* Get the full pathname to the namespace node */ 254249109Sjkim 255249109Sjkim TargetPath.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 256249109Sjkim Status = AcpiNsHandleToPathname (Node, &TargetPath); 257249109Sjkim if (ACPI_FAILURE (Status)) 258249109Sjkim { 259249109Sjkim return; 260249109Sjkim } 261249109Sjkim 262249109Sjkim /* [1] - Skip the opening backslash for the path */ 263249109Sjkim 264249109Sjkim strcpy (MsgBuffer, "\""); 265249109Sjkim strcat (MsgBuffer, &((char *) TargetPath.Pointer)[1]); 266249109Sjkim strcat (MsgBuffer, "\","); 267249109Sjkim ACPI_FREE (TargetPath.Pointer); 268249109Sjkim 269249109Sjkim /* 270249109Sjkim * Max offset is 4G, constrained by 32-bit ACPI table length. 271249109Sjkim * Max Length for Integers is 8 bytes. 272249109Sjkim */ 273249109Sjkim FlPrintFile (FileId, 274249109Sjkim " {%-29s 0x%8.8X, 0x%2.2X, 0x%8.8X%8.8X}, /* %s */\n", 275249109Sjkim MsgBuffer, Offset, AmlOpcode, ACPI_FORMAT_UINT64 (Value), OpName); 276249109Sjkim} 277249109Sjkim 278249109Sjkim 279249109Sjkim/******************************************************************************* 280249109Sjkim * 281249109Sjkim * FUNCTION: LsDoOffsetTableHeader, LsDoOffsetTableFooter 282249109Sjkim * 283249109Sjkim * PARAMETERS: FileId - ID of current listing file 284249109Sjkim * 285249109Sjkim * RETURN: None 286249109Sjkim * 287249109Sjkim * DESCRIPTION: Header and footer for the offset table file. 288249109Sjkim * 289249109Sjkim ******************************************************************************/ 290249109Sjkim 291249109Sjkimvoid 292249109SjkimLsDoOffsetTableHeader ( 293249109Sjkim UINT32 FileId) 294249109Sjkim{ 295249109Sjkim 296249109Sjkim Gbl_CurrentAmlOffset = 0; 297249109Sjkim 298249109Sjkim FlPrintFile (FileId, 299249109Sjkim "#ifndef __AML_OFFSET_TABLE_H\n" 300249109Sjkim "#define __AML_OFFSET_TABLE_H\n\n"); 301249109Sjkim 302249109Sjkim FlPrintFile (FileId, "typedef struct {\n" 303249109Sjkim " char *Pathname;\n" 304249109Sjkim " unsigned long Offset;\n" 305249109Sjkim " unsigned char AmlOpcode;\n" 306249109Sjkim " unsigned long long AmlValue;\n" 307249109Sjkim "} AML_OFFSET_TABLE_ENTRY;\n\n"); 308249109Sjkim 309249109Sjkim FlPrintFile (FileId, 310249109Sjkim "#endif /* __AML_OFFSET_TABLE_H */\n\n"); 311249109Sjkim 312249109Sjkim FlPrintFile (FileId, 313249109Sjkim "AML_OFFSET_TABLE_ENTRY %s_%s_OffsetTable[] =\n{\n", 314249109Sjkim Gbl_TableSignature, Gbl_TableId); 315249109Sjkim} 316249109Sjkim 317249109Sjkim 318249109Sjkimvoid 319249109SjkimLsDoOffsetTableFooter ( 320249109Sjkim UINT32 FileId) 321249109Sjkim{ 322249109Sjkim 323249109Sjkim FlPrintFile (FileId, 324249109Sjkim " {0,0,0,0} /* Table terminator */\n};\n\n"); 325249109Sjkim Gbl_CurrentAmlOffset = 0; 326249109Sjkim} 327