dtsubtable.c revision 245582
1230557Sjimharris/****************************************************************************** 2230557Sjimharris * 3230557Sjimharris * Module Name: dtsubtable.c - handling of subtables within ACPI tables 4230557Sjimharris * 5230557Sjimharris *****************************************************************************/ 6230557Sjimharris 7230557Sjimharris/* 8230557Sjimharris * Copyright (C) 2000 - 2013, Intel Corp. 9230557Sjimharris * All rights reserved. 10230557Sjimharris * 11230557Sjimharris * Redistribution and use in source and binary forms, with or without 12230557Sjimharris * modification, are permitted provided that the following conditions 13230557Sjimharris * are met: 14230557Sjimharris * 1. Redistributions of source code must retain the above copyright 15230557Sjimharris * notice, this list of conditions, and the following disclaimer, 16230557Sjimharris * without modification. 17230557Sjimharris * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18230557Sjimharris * substantially similar to the "NO WARRANTY" disclaimer below 19230557Sjimharris * ("Disclaimer") and any redistribution must be conditioned upon 20230557Sjimharris * including a substantially similar Disclaimer requirement for further 21230557Sjimharris * binary redistribution. 22230557Sjimharris * 3. Neither the names of the above-listed copyright holders nor the names 23230557Sjimharris * of any contributors may be used to endorse or promote products derived 24230557Sjimharris * from this software without specific prior written permission. 25230557Sjimharris * 26230557Sjimharris * Alternatively, this software may be distributed under the terms of the 27230557Sjimharris * GNU General Public License ("GPL") version 2 as published by the Free 28230557Sjimharris * Software Foundation. 29230557Sjimharris * 30230557Sjimharris * NO WARRANTY 31230557Sjimharris * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32230557Sjimharris * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33230557Sjimharris * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34230557Sjimharris * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35230557Sjimharris * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36230557Sjimharris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37230557Sjimharris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38230557Sjimharris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39230557Sjimharris * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40230557Sjimharris * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41230557Sjimharris * POSSIBILITY OF SUCH DAMAGES. 42230557Sjimharris */ 43230557Sjimharris 44230557Sjimharris#define __DTSUBTABLE_C__ 45230557Sjimharris 46230557Sjimharris#include <contrib/dev/acpica/compiler/aslcompiler.h> 47230557Sjimharris#include <contrib/dev/acpica/compiler/dtcompiler.h> 48230557Sjimharris 49230557Sjimharris#define _COMPONENT DT_COMPILER 50230557Sjimharris ACPI_MODULE_NAME ("dtsubtable") 51230557Sjimharris 52230557Sjimharris 53230557Sjimharris/****************************************************************************** 54230557Sjimharris * 55230557Sjimharris * FUNCTION: DtCreateSubtable 56230557Sjimharris * 57230557Sjimharris * PARAMETERS: Buffer - Input buffer 58230557Sjimharris * Length - Buffer length 59230557Sjimharris * RetSubtable - Returned newly created subtable 60230557Sjimharris * 61230557Sjimharris * RETURN: None 62230557Sjimharris * 63230557Sjimharris * DESCRIPTION: Create a subtable that is not listed with ACPI_DMTABLE_INFO 64230557Sjimharris * For example, FACS has 24 bytes reserved at the end 65230557Sjimharris * and it's not listed at AcpiDmTableInfoFacs 66230557Sjimharris * 67230557Sjimharris *****************************************************************************/ 68230557Sjimharris 69230557Sjimharrisvoid 70230557SjimharrisDtCreateSubtable ( 71230557Sjimharris UINT8 *Buffer, 72230557Sjimharris UINT32 Length, 73230557Sjimharris DT_SUBTABLE **RetSubtable) 74230557Sjimharris{ 75230557Sjimharris DT_SUBTABLE *Subtable; 76230557Sjimharris 77230557Sjimharris 78230557Sjimharris Subtable = UtLocalCalloc (sizeof (DT_SUBTABLE)); 79230557Sjimharris 80230557Sjimharris /* Create a new buffer for the subtable data */ 81230557Sjimharris 82230557Sjimharris Subtable->Buffer = UtLocalCalloc (Length); 83230557Sjimharris ACPI_MEMCPY (Subtable->Buffer, Buffer, Length); 84230557Sjimharris 85230557Sjimharris Subtable->Length = Length; 86230557Sjimharris Subtable->TotalLength = Length; 87230557Sjimharris 88230557Sjimharris *RetSubtable = Subtable; 89230557Sjimharris} 90230557Sjimharris 91230557Sjimharris 92230557Sjimharris/****************************************************************************** 93230557Sjimharris * 94230557Sjimharris * FUNCTION: DtInsertSubtable 95230557Sjimharris * 96230557Sjimharris * PARAMETERS: ParentTable - The Parent of the new subtable 97230557Sjimharris * Subtable - The new subtable to insert 98230557Sjimharris * 99230557Sjimharris * RETURN: None 100230557Sjimharris * 101230557Sjimharris * DESCRIPTION: Insert the new subtable to the parent table 102230557Sjimharris * 103230557Sjimharris *****************************************************************************/ 104230557Sjimharris 105230557Sjimharrisvoid 106230557SjimharrisDtInsertSubtable ( 107230557Sjimharris DT_SUBTABLE *ParentTable, 108230557Sjimharris DT_SUBTABLE *Subtable) 109230557Sjimharris{ 110230557Sjimharris DT_SUBTABLE *ChildTable; 111230557Sjimharris 112230557Sjimharris 113230557Sjimharris Subtable->Peer = NULL; 114230557Sjimharris Subtable->Parent = ParentTable; 115230557Sjimharris Subtable->Depth = ParentTable->Depth + 1; 116230557Sjimharris 117230557Sjimharris /* Link the new entry into the child list */ 118230557Sjimharris 119230557Sjimharris if (!ParentTable->Child) 120230557Sjimharris { 121230557Sjimharris ParentTable->Child = Subtable; 122230557Sjimharris } 123230557Sjimharris else 124230557Sjimharris { 125230557Sjimharris /* Walk to the end of the child list */ 126230557Sjimharris 127230557Sjimharris ChildTable = ParentTable->Child; 128230557Sjimharris while (ChildTable->Peer) 129230557Sjimharris { 130230557Sjimharris ChildTable = ChildTable->Peer; 131230557Sjimharris } 132230557Sjimharris 133230557Sjimharris /* Add new subtable at the end of the child list */ 134230557Sjimharris 135230557Sjimharris ChildTable->Peer = Subtable; 136230557Sjimharris } 137230557Sjimharris} 138230557Sjimharris 139230557Sjimharris 140230557Sjimharris/****************************************************************************** 141230557Sjimharris * 142230557Sjimharris * FUNCTION: DtPushSubtable 143230557Sjimharris * 144230557Sjimharris * PARAMETERS: Subtable - Subtable to push 145230557Sjimharris * 146230557Sjimharris * RETURN: None 147230557Sjimharris * 148230557Sjimharris * DESCRIPTION: Push a subtable onto a subtable stack 149230557Sjimharris * 150230557Sjimharris *****************************************************************************/ 151230557Sjimharris 152230557Sjimharrisvoid 153230557SjimharrisDtPushSubtable ( 154230557Sjimharris DT_SUBTABLE *Subtable) 155230557Sjimharris{ 156230557Sjimharris 157230557Sjimharris Subtable->StackTop = Gbl_SubtableStack; 158230557Sjimharris Gbl_SubtableStack = Subtable; 159230557Sjimharris} 160230557Sjimharris 161230557Sjimharris 162230557Sjimharris/****************************************************************************** 163230557Sjimharris * 164230557Sjimharris * FUNCTION: DtPopSubtable 165230557Sjimharris * 166230557Sjimharris * PARAMETERS: None 167230557Sjimharris * 168230557Sjimharris * RETURN: None 169230557Sjimharris * 170230557Sjimharris * DESCRIPTION: Pop a subtable from a subtable stack. Uses global SubtableStack 171230557Sjimharris * 172230557Sjimharris *****************************************************************************/ 173230557Sjimharris 174230557Sjimharrisvoid 175230557SjimharrisDtPopSubtable ( 176230557Sjimharris void) 177230557Sjimharris{ 178230557Sjimharris DT_SUBTABLE *Subtable; 179230557Sjimharris 180230557Sjimharris 181230557Sjimharris Subtable = Gbl_SubtableStack; 182230557Sjimharris 183230557Sjimharris if (Subtable) 184230557Sjimharris { 185230557Sjimharris Gbl_SubtableStack = Subtable->StackTop; 186230557Sjimharris } 187230557Sjimharris} 188230557Sjimharris 189230557Sjimharris 190230557Sjimharris/****************************************************************************** 191230557Sjimharris * 192230557Sjimharris * FUNCTION: DtPeekSubtable 193230557Sjimharris * 194230557Sjimharris * PARAMETERS: None 195230557Sjimharris * 196230557Sjimharris * RETURN: The subtable on top of stack 197230557Sjimharris * 198230557Sjimharris * DESCRIPTION: Get the subtable on top of stack 199230557Sjimharris * 200230557Sjimharris *****************************************************************************/ 201230557Sjimharris 202230557SjimharrisDT_SUBTABLE * 203230557SjimharrisDtPeekSubtable ( 204230557Sjimharris void) 205230557Sjimharris{ 206230557Sjimharris 207230557Sjimharris return (Gbl_SubtableStack); 208230557Sjimharris} 209230557Sjimharris 210230557Sjimharris 211230557Sjimharris/****************************************************************************** 212230557Sjimharris * 213230557Sjimharris * FUNCTION: DtGetNextSubtable 214230557Sjimharris * 215230557Sjimharris * PARAMETERS: ParentTable - Parent table whose children we are 216230557Sjimharris * getting 217230557Sjimharris * ChildTable - Previous child that was found. 218230557Sjimharris * The NEXT child will be returned 219230557Sjimharris * 220230557Sjimharris * RETURN: Pointer to the NEXT child or NULL if none is found. 221230557Sjimharris * 222230557Sjimharris * DESCRIPTION: Return the next peer subtable within the tree. 223230557Sjimharris * 224230557Sjimharris *****************************************************************************/ 225230557Sjimharris 226230557SjimharrisDT_SUBTABLE * 227230557SjimharrisDtGetNextSubtable ( 228230557Sjimharris DT_SUBTABLE *ParentTable, 229230557Sjimharris DT_SUBTABLE *ChildTable) 230230557Sjimharris{ 231230557Sjimharris ACPI_FUNCTION_ENTRY (); 232230557Sjimharris 233230557Sjimharris 234230557Sjimharris if (!ChildTable) 235230557Sjimharris { 236230557Sjimharris /* It's really the parent's _scope_ that we want */ 237230557Sjimharris 238230557Sjimharris return (ParentTable->Child); 239230557Sjimharris } 240230557Sjimharris 241230557Sjimharris /* Otherwise just return the next peer (NULL if at end-of-list) */ 242230557Sjimharris 243230557Sjimharris return (ChildTable->Peer); 244} 245 246 247/****************************************************************************** 248 * 249 * FUNCTION: DtGetParentSubtable 250 * 251 * PARAMETERS: Subtable - Current subtable 252 * 253 * RETURN: Parent of the given subtable 254 * 255 * DESCRIPTION: Get the parent of the given subtable in the tree 256 * 257 *****************************************************************************/ 258 259DT_SUBTABLE * 260DtGetParentSubtable ( 261 DT_SUBTABLE *Subtable) 262{ 263 264 if (!Subtable) 265 { 266 return (NULL); 267 } 268 269 return (Subtable->Parent); 270} 271 272 273/****************************************************************************** 274 * 275 * FUNCTION: DtGetSubtableLength 276 * 277 * PARAMETERS: Field - Current field list pointer 278 * Info - Data table info 279 * 280 * RETURN: Subtable length 281 * 282 * DESCRIPTION: Get length of bytes needed to compile the subtable 283 * 284 *****************************************************************************/ 285 286UINT32 287DtGetSubtableLength ( 288 DT_FIELD *Field, 289 ACPI_DMTABLE_INFO *Info) 290{ 291 UINT32 ByteLength = 0; 292 UINT8 Step; 293 UINT8 i; 294 295 296 /* Walk entire Info table; Null name terminates */ 297 298 for (; Info->Name; Info++) 299 { 300 if (Info->Opcode == ACPI_DMT_EXTRA_TEXT) 301 { 302 continue; 303 } 304 305 if (!Field) 306 { 307 goto Error; 308 } 309 310 ByteLength += DtGetFieldLength (Field, Info); 311 312 switch (Info->Opcode) 313 { 314 case ACPI_DMT_GAS: 315 Step = 5; 316 break; 317 318 case ACPI_DMT_HESTNTFY: 319 Step = 9; 320 break; 321 322 default: 323 Step = 1; 324 break; 325 } 326 327 for (i = 0; i < Step; i++) 328 { 329 if (!Field) 330 { 331 goto Error; 332 } 333 334 Field = Field->Next; 335 } 336 } 337 338 return (ByteLength); 339 340Error: 341 if (!Field) 342 { 343 sprintf (MsgBuffer, "Found NULL field - Field name \"%s\" needed", 344 Info->Name); 345 DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer); 346 } 347 348 return (ASL_EOF); 349} 350 351 352/****************************************************************************** 353 * 354 * FUNCTION: DtSetSubtableLength 355 * 356 * PARAMETERS: Subtable - Subtable 357 * 358 * RETURN: None 359 * 360 * DESCRIPTION: Set length of the subtable into its length field 361 * 362 *****************************************************************************/ 363 364void 365DtSetSubtableLength ( 366 DT_SUBTABLE *Subtable) 367{ 368 369 if (!Subtable->LengthField) 370 { 371 return; 372 } 373 374 ACPI_MEMCPY (Subtable->LengthField, &Subtable->TotalLength, 375 Subtable->SizeOfLengthField); 376} 377