1a88e22b7SJung-uk Kim /****************************************************************************** 2a88e22b7SJung-uk Kim * 3a88e22b7SJung-uk Kim * Module Name: dtsubtable.c - handling of subtables within ACPI tables 4a88e22b7SJung-uk Kim * 5a88e22b7SJung-uk Kim *****************************************************************************/ 6a88e22b7SJung-uk Kim 7d244b227SJung-uk Kim /* 81c0e1b6dSJung-uk Kim * Copyright (C) 2000 - 2015, Intel Corp. 9a88e22b7SJung-uk Kim * All rights reserved. 10a88e22b7SJung-uk Kim * 11d244b227SJung-uk Kim * Redistribution and use in source and binary forms, with or without 12d244b227SJung-uk Kim * modification, are permitted provided that the following conditions 13d244b227SJung-uk Kim * are met: 14d244b227SJung-uk Kim * 1. Redistributions of source code must retain the above copyright 15d244b227SJung-uk Kim * notice, this list of conditions, and the following disclaimer, 16d244b227SJung-uk Kim * without modification. 17d244b227SJung-uk Kim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18d244b227SJung-uk Kim * substantially similar to the "NO WARRANTY" disclaimer below 19d244b227SJung-uk Kim * ("Disclaimer") and any redistribution must be conditioned upon 20d244b227SJung-uk Kim * including a substantially similar Disclaimer requirement for further 21d244b227SJung-uk Kim * binary redistribution. 22d244b227SJung-uk Kim * 3. Neither the names of the above-listed copyright holders nor the names 23d244b227SJung-uk Kim * of any contributors may be used to endorse or promote products derived 24d244b227SJung-uk Kim * from this software without specific prior written permission. 25a88e22b7SJung-uk Kim * 26d244b227SJung-uk Kim * Alternatively, this software may be distributed under the terms of the 27d244b227SJung-uk Kim * GNU General Public License ("GPL") version 2 as published by the Free 28d244b227SJung-uk Kim * Software Foundation. 29a88e22b7SJung-uk Kim * 30d244b227SJung-uk Kim * NO WARRANTY 31d244b227SJung-uk Kim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32d244b227SJung-uk Kim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33d244b227SJung-uk Kim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34d244b227SJung-uk Kim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35d244b227SJung-uk Kim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36d244b227SJung-uk Kim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37d244b227SJung-uk Kim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38d244b227SJung-uk Kim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39d244b227SJung-uk Kim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40d244b227SJung-uk Kim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41d244b227SJung-uk Kim * POSSIBILITY OF SUCH DAMAGES. 42d244b227SJung-uk Kim */ 43a88e22b7SJung-uk Kim 44a88e22b7SJung-uk Kim #include <contrib/dev/acpica/compiler/aslcompiler.h> 45a88e22b7SJung-uk Kim #include <contrib/dev/acpica/compiler/dtcompiler.h> 46a88e22b7SJung-uk Kim 47a88e22b7SJung-uk Kim #define _COMPONENT DT_COMPILER 48a88e22b7SJung-uk Kim ACPI_MODULE_NAME ("dtsubtable") 49a88e22b7SJung-uk Kim 50a88e22b7SJung-uk Kim 51a88e22b7SJung-uk Kim /****************************************************************************** 52a88e22b7SJung-uk Kim * 53a88e22b7SJung-uk Kim * FUNCTION: DtCreateSubtable 54a88e22b7SJung-uk Kim * 55a88e22b7SJung-uk Kim * PARAMETERS: Buffer - Input buffer 56a88e22b7SJung-uk Kim * Length - Buffer length 57a88e22b7SJung-uk Kim * RetSubtable - Returned newly created subtable 58a88e22b7SJung-uk Kim * 59a88e22b7SJung-uk Kim * RETURN: None 60a88e22b7SJung-uk Kim * 61a88e22b7SJung-uk Kim * DESCRIPTION: Create a subtable that is not listed with ACPI_DMTABLE_INFO 62a88e22b7SJung-uk Kim * For example, FACS has 24 bytes reserved at the end 63a88e22b7SJung-uk Kim * and it's not listed at AcpiDmTableInfoFacs 64a88e22b7SJung-uk Kim * 65a88e22b7SJung-uk Kim *****************************************************************************/ 66a88e22b7SJung-uk Kim 67a88e22b7SJung-uk Kim void 68a88e22b7SJung-uk Kim DtCreateSubtable ( 69a88e22b7SJung-uk Kim UINT8 *Buffer, 70a88e22b7SJung-uk Kim UINT32 Length, 71a88e22b7SJung-uk Kim DT_SUBTABLE **RetSubtable) 72a88e22b7SJung-uk Kim { 73a88e22b7SJung-uk Kim DT_SUBTABLE *Subtable; 74313a0c13SJung-uk Kim char *String; 75a88e22b7SJung-uk Kim 76a88e22b7SJung-uk Kim 77313a0c13SJung-uk Kim Subtable = UtSubtableCacheCalloc (); 78a88e22b7SJung-uk Kim 79a88e22b7SJung-uk Kim /* Create a new buffer for the subtable data */ 80a88e22b7SJung-uk Kim 81313a0c13SJung-uk Kim String = UtStringCacheCalloc (Length); 82313a0c13SJung-uk Kim Subtable->Buffer = ACPI_CAST_PTR (UINT8, String); 83a88e22b7SJung-uk Kim ACPI_MEMCPY (Subtable->Buffer, Buffer, Length); 84a88e22b7SJung-uk Kim 85a88e22b7SJung-uk Kim Subtable->Length = Length; 86a88e22b7SJung-uk Kim Subtable->TotalLength = Length; 87a88e22b7SJung-uk Kim 88a88e22b7SJung-uk Kim *RetSubtable = Subtable; 89a88e22b7SJung-uk Kim } 90a88e22b7SJung-uk Kim 91a88e22b7SJung-uk Kim 92a88e22b7SJung-uk Kim /****************************************************************************** 93a88e22b7SJung-uk Kim * 94a88e22b7SJung-uk Kim * FUNCTION: DtInsertSubtable 95a88e22b7SJung-uk Kim * 96a88e22b7SJung-uk Kim * PARAMETERS: ParentTable - The Parent of the new subtable 97a88e22b7SJung-uk Kim * Subtable - The new subtable to insert 98a88e22b7SJung-uk Kim * 99a88e22b7SJung-uk Kim * RETURN: None 100a88e22b7SJung-uk Kim * 101a88e22b7SJung-uk Kim * DESCRIPTION: Insert the new subtable to the parent table 102a88e22b7SJung-uk Kim * 103a88e22b7SJung-uk Kim *****************************************************************************/ 104a88e22b7SJung-uk Kim 105a88e22b7SJung-uk Kim void 106a88e22b7SJung-uk Kim DtInsertSubtable ( 107a88e22b7SJung-uk Kim DT_SUBTABLE *ParentTable, 108a88e22b7SJung-uk Kim DT_SUBTABLE *Subtable) 109a88e22b7SJung-uk Kim { 110a88e22b7SJung-uk Kim DT_SUBTABLE *ChildTable; 111a88e22b7SJung-uk Kim 112a88e22b7SJung-uk Kim 113a88e22b7SJung-uk Kim Subtable->Peer = NULL; 114a88e22b7SJung-uk Kim Subtable->Parent = ParentTable; 115efcc2a30SJung-uk Kim Subtable->Depth = ParentTable->Depth + 1; 116a88e22b7SJung-uk Kim 117a88e22b7SJung-uk Kim /* Link the new entry into the child list */ 118a88e22b7SJung-uk Kim 119a88e22b7SJung-uk Kim if (!ParentTable->Child) 120a88e22b7SJung-uk Kim { 121a88e22b7SJung-uk Kim ParentTable->Child = Subtable; 122a88e22b7SJung-uk Kim } 123a88e22b7SJung-uk Kim else 124a88e22b7SJung-uk Kim { 125a88e22b7SJung-uk Kim /* Walk to the end of the child list */ 126a88e22b7SJung-uk Kim 127a88e22b7SJung-uk Kim ChildTable = ParentTable->Child; 128a88e22b7SJung-uk Kim while (ChildTable->Peer) 129a88e22b7SJung-uk Kim { 130a88e22b7SJung-uk Kim ChildTable = ChildTable->Peer; 131a88e22b7SJung-uk Kim } 132a88e22b7SJung-uk Kim 133a88e22b7SJung-uk Kim /* Add new subtable at the end of the child list */ 134a88e22b7SJung-uk Kim 135a88e22b7SJung-uk Kim ChildTable->Peer = Subtable; 136a88e22b7SJung-uk Kim } 137a88e22b7SJung-uk Kim } 138a88e22b7SJung-uk Kim 139a88e22b7SJung-uk Kim 140a88e22b7SJung-uk Kim /****************************************************************************** 141a88e22b7SJung-uk Kim * 142a88e22b7SJung-uk Kim * FUNCTION: DtPushSubtable 143a88e22b7SJung-uk Kim * 144a88e22b7SJung-uk Kim * PARAMETERS: Subtable - Subtable to push 145a88e22b7SJung-uk Kim * 146a88e22b7SJung-uk Kim * RETURN: None 147a88e22b7SJung-uk Kim * 148a88e22b7SJung-uk Kim * DESCRIPTION: Push a subtable onto a subtable stack 149a88e22b7SJung-uk Kim * 150a88e22b7SJung-uk Kim *****************************************************************************/ 151a88e22b7SJung-uk Kim 152a88e22b7SJung-uk Kim void 153a88e22b7SJung-uk Kim DtPushSubtable ( 154a88e22b7SJung-uk Kim DT_SUBTABLE *Subtable) 155a88e22b7SJung-uk Kim { 156a88e22b7SJung-uk Kim 157a88e22b7SJung-uk Kim Subtable->StackTop = Gbl_SubtableStack; 158a88e22b7SJung-uk Kim Gbl_SubtableStack = Subtable; 159a88e22b7SJung-uk Kim } 160a88e22b7SJung-uk Kim 161a88e22b7SJung-uk Kim 162a88e22b7SJung-uk Kim /****************************************************************************** 163a88e22b7SJung-uk Kim * 164a88e22b7SJung-uk Kim * FUNCTION: DtPopSubtable 165a88e22b7SJung-uk Kim * 166a88e22b7SJung-uk Kim * PARAMETERS: None 167a88e22b7SJung-uk Kim * 168a88e22b7SJung-uk Kim * RETURN: None 169a88e22b7SJung-uk Kim * 170a88e22b7SJung-uk Kim * DESCRIPTION: Pop a subtable from a subtable stack. Uses global SubtableStack 171a88e22b7SJung-uk Kim * 172a88e22b7SJung-uk Kim *****************************************************************************/ 173a88e22b7SJung-uk Kim 174a88e22b7SJung-uk Kim void 175a88e22b7SJung-uk Kim DtPopSubtable ( 176a88e22b7SJung-uk Kim void) 177a88e22b7SJung-uk Kim { 178a88e22b7SJung-uk Kim DT_SUBTABLE *Subtable; 179a88e22b7SJung-uk Kim 180a88e22b7SJung-uk Kim 181a88e22b7SJung-uk Kim Subtable = Gbl_SubtableStack; 182a88e22b7SJung-uk Kim 183a88e22b7SJung-uk Kim if (Subtable) 184a88e22b7SJung-uk Kim { 185a88e22b7SJung-uk Kim Gbl_SubtableStack = Subtable->StackTop; 186a88e22b7SJung-uk Kim } 187a88e22b7SJung-uk Kim } 188a88e22b7SJung-uk Kim 189a88e22b7SJung-uk Kim 190a88e22b7SJung-uk Kim /****************************************************************************** 191a88e22b7SJung-uk Kim * 192a88e22b7SJung-uk Kim * FUNCTION: DtPeekSubtable 193a88e22b7SJung-uk Kim * 194a88e22b7SJung-uk Kim * PARAMETERS: None 195a88e22b7SJung-uk Kim * 196a88e22b7SJung-uk Kim * RETURN: The subtable on top of stack 197a88e22b7SJung-uk Kim * 198a88e22b7SJung-uk Kim * DESCRIPTION: Get the subtable on top of stack 199a88e22b7SJung-uk Kim * 200a88e22b7SJung-uk Kim *****************************************************************************/ 201a88e22b7SJung-uk Kim 202a88e22b7SJung-uk Kim DT_SUBTABLE * 203a88e22b7SJung-uk Kim DtPeekSubtable ( 204a88e22b7SJung-uk Kim void) 205a88e22b7SJung-uk Kim { 206a88e22b7SJung-uk Kim 207a88e22b7SJung-uk Kim return (Gbl_SubtableStack); 208a88e22b7SJung-uk Kim } 209a88e22b7SJung-uk Kim 210a88e22b7SJung-uk Kim 211a88e22b7SJung-uk Kim /****************************************************************************** 212a88e22b7SJung-uk Kim * 213a88e22b7SJung-uk Kim * FUNCTION: DtGetNextSubtable 214a88e22b7SJung-uk Kim * 215a88e22b7SJung-uk Kim * PARAMETERS: ParentTable - Parent table whose children we are 216a88e22b7SJung-uk Kim * getting 217a88e22b7SJung-uk Kim * ChildTable - Previous child that was found. 218a88e22b7SJung-uk Kim * The NEXT child will be returned 219a88e22b7SJung-uk Kim * 220a88e22b7SJung-uk Kim * RETURN: Pointer to the NEXT child or NULL if none is found. 221a88e22b7SJung-uk Kim * 222a88e22b7SJung-uk Kim * DESCRIPTION: Return the next peer subtable within the tree. 223a88e22b7SJung-uk Kim * 224a88e22b7SJung-uk Kim *****************************************************************************/ 225a88e22b7SJung-uk Kim 226a88e22b7SJung-uk Kim DT_SUBTABLE * 227a88e22b7SJung-uk Kim DtGetNextSubtable ( 228a88e22b7SJung-uk Kim DT_SUBTABLE *ParentTable, 229a88e22b7SJung-uk Kim DT_SUBTABLE *ChildTable) 230a88e22b7SJung-uk Kim { 231a88e22b7SJung-uk Kim ACPI_FUNCTION_ENTRY (); 232a88e22b7SJung-uk Kim 233a88e22b7SJung-uk Kim 234a88e22b7SJung-uk Kim if (!ChildTable) 235a88e22b7SJung-uk Kim { 236a88e22b7SJung-uk Kim /* It's really the parent's _scope_ that we want */ 237a88e22b7SJung-uk Kim 238a88e22b7SJung-uk Kim return (ParentTable->Child); 239a88e22b7SJung-uk Kim } 240a88e22b7SJung-uk Kim 241a88e22b7SJung-uk Kim /* Otherwise just return the next peer (NULL if at end-of-list) */ 242a88e22b7SJung-uk Kim 243a88e22b7SJung-uk Kim return (ChildTable->Peer); 244a88e22b7SJung-uk Kim } 245a88e22b7SJung-uk Kim 246a88e22b7SJung-uk Kim 247a88e22b7SJung-uk Kim /****************************************************************************** 248a88e22b7SJung-uk Kim * 249a88e22b7SJung-uk Kim * FUNCTION: DtGetParentSubtable 250a88e22b7SJung-uk Kim * 251a88e22b7SJung-uk Kim * PARAMETERS: Subtable - Current subtable 252a88e22b7SJung-uk Kim * 253a88e22b7SJung-uk Kim * RETURN: Parent of the given subtable 254a88e22b7SJung-uk Kim * 255a88e22b7SJung-uk Kim * DESCRIPTION: Get the parent of the given subtable in the tree 256a88e22b7SJung-uk Kim * 257a88e22b7SJung-uk Kim *****************************************************************************/ 258a88e22b7SJung-uk Kim 259a88e22b7SJung-uk Kim DT_SUBTABLE * 260a88e22b7SJung-uk Kim DtGetParentSubtable ( 261a88e22b7SJung-uk Kim DT_SUBTABLE *Subtable) 262a88e22b7SJung-uk Kim { 263a88e22b7SJung-uk Kim 264a88e22b7SJung-uk Kim if (!Subtable) 265a88e22b7SJung-uk Kim { 266a88e22b7SJung-uk Kim return (NULL); 267a88e22b7SJung-uk Kim } 268a88e22b7SJung-uk Kim 269a88e22b7SJung-uk Kim return (Subtable->Parent); 270a88e22b7SJung-uk Kim } 271a88e22b7SJung-uk Kim 272a88e22b7SJung-uk Kim 273a88e22b7SJung-uk Kim /****************************************************************************** 274a88e22b7SJung-uk Kim * 275a88e22b7SJung-uk Kim * FUNCTION: DtGetSubtableLength 276a88e22b7SJung-uk Kim * 277a88e22b7SJung-uk Kim * PARAMETERS: Field - Current field list pointer 278a88e22b7SJung-uk Kim * Info - Data table info 279a88e22b7SJung-uk Kim * 280a88e22b7SJung-uk Kim * RETURN: Subtable length 281a88e22b7SJung-uk Kim * 282a88e22b7SJung-uk Kim * DESCRIPTION: Get length of bytes needed to compile the subtable 283a88e22b7SJung-uk Kim * 284a88e22b7SJung-uk Kim *****************************************************************************/ 285a88e22b7SJung-uk Kim 286a88e22b7SJung-uk Kim UINT32 287a88e22b7SJung-uk Kim DtGetSubtableLength ( 288a88e22b7SJung-uk Kim DT_FIELD *Field, 289a88e22b7SJung-uk Kim ACPI_DMTABLE_INFO *Info) 290a88e22b7SJung-uk Kim { 291a88e22b7SJung-uk Kim UINT32 ByteLength = 0; 292d052a1ccSJung-uk Kim UINT8 Step; 293d052a1ccSJung-uk Kim UINT8 i; 294a88e22b7SJung-uk Kim 295a88e22b7SJung-uk Kim 296a88e22b7SJung-uk Kim /* Walk entire Info table; Null name terminates */ 297a88e22b7SJung-uk Kim 298a88e22b7SJung-uk Kim for (; Info->Name; Info++) 299a88e22b7SJung-uk Kim { 3003f0275a0SJung-uk Kim if (Info->Opcode == ACPI_DMT_EXTRA_TEXT) 3013f0275a0SJung-uk Kim { 3023f0275a0SJung-uk Kim continue; 3033f0275a0SJung-uk Kim } 3043f0275a0SJung-uk Kim 305d052a1ccSJung-uk Kim if (!Field) 306d052a1ccSJung-uk Kim { 307d052a1ccSJung-uk Kim goto Error; 308d052a1ccSJung-uk Kim } 309d052a1ccSJung-uk Kim 310a88e22b7SJung-uk Kim ByteLength += DtGetFieldLength (Field, Info); 311d052a1ccSJung-uk Kim 312d052a1ccSJung-uk Kim switch (Info->Opcode) 313d052a1ccSJung-uk Kim { 314d052a1ccSJung-uk Kim case ACPI_DMT_GAS: 315a9d8d09cSJung-uk Kim 316d052a1ccSJung-uk Kim Step = 5; 317d052a1ccSJung-uk Kim break; 318d052a1ccSJung-uk Kim 319d052a1ccSJung-uk Kim case ACPI_DMT_HESTNTFY: 320a9d8d09cSJung-uk Kim 321d052a1ccSJung-uk Kim Step = 9; 322d052a1ccSJung-uk Kim break; 323d052a1ccSJung-uk Kim 324*a371a5fdSJung-uk Kim case ACPI_DMT_IORTMEM: 325*a371a5fdSJung-uk Kim 326*a371a5fdSJung-uk Kim Step = 10; 327*a371a5fdSJung-uk Kim break; 328*a371a5fdSJung-uk Kim 329d052a1ccSJung-uk Kim default: 330a9d8d09cSJung-uk Kim 331d052a1ccSJung-uk Kim Step = 1; 332d052a1ccSJung-uk Kim break; 333d052a1ccSJung-uk Kim } 334d052a1ccSJung-uk Kim 335d052a1ccSJung-uk Kim for (i = 0; i < Step; i++) 336d052a1ccSJung-uk Kim { 337d052a1ccSJung-uk Kim if (!Field) 338d052a1ccSJung-uk Kim { 339d052a1ccSJung-uk Kim goto Error; 340d052a1ccSJung-uk Kim } 341d052a1ccSJung-uk Kim 342d052a1ccSJung-uk Kim Field = Field->Next; 343d052a1ccSJung-uk Kim } 344a88e22b7SJung-uk Kim } 345a88e22b7SJung-uk Kim 346a88e22b7SJung-uk Kim return (ByteLength); 347d052a1ccSJung-uk Kim 348d052a1ccSJung-uk Kim Error: 349d052a1ccSJung-uk Kim if (!Field) 350d052a1ccSJung-uk Kim { 351d052a1ccSJung-uk Kim sprintf (MsgBuffer, "Found NULL field - Field name \"%s\" needed", 352d052a1ccSJung-uk Kim Info->Name); 353d052a1ccSJung-uk Kim DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer); 354d052a1ccSJung-uk Kim } 355d052a1ccSJung-uk Kim 356d052a1ccSJung-uk Kim return (ASL_EOF); 357a88e22b7SJung-uk Kim } 358a88e22b7SJung-uk Kim 359a88e22b7SJung-uk Kim 360a88e22b7SJung-uk Kim /****************************************************************************** 361a88e22b7SJung-uk Kim * 362a88e22b7SJung-uk Kim * FUNCTION: DtSetSubtableLength 363a88e22b7SJung-uk Kim * 364a88e22b7SJung-uk Kim * PARAMETERS: Subtable - Subtable 365a88e22b7SJung-uk Kim * 366a88e22b7SJung-uk Kim * RETURN: None 367a88e22b7SJung-uk Kim * 368a88e22b7SJung-uk Kim * DESCRIPTION: Set length of the subtable into its length field 369a88e22b7SJung-uk Kim * 370a88e22b7SJung-uk Kim *****************************************************************************/ 371a88e22b7SJung-uk Kim 372a88e22b7SJung-uk Kim void 373a88e22b7SJung-uk Kim DtSetSubtableLength ( 374a88e22b7SJung-uk Kim DT_SUBTABLE *Subtable) 375a88e22b7SJung-uk Kim { 376a88e22b7SJung-uk Kim 377a88e22b7SJung-uk Kim if (!Subtable->LengthField) 378a88e22b7SJung-uk Kim { 379a88e22b7SJung-uk Kim return; 380a88e22b7SJung-uk Kim } 381a88e22b7SJung-uk Kim 382a88e22b7SJung-uk Kim ACPI_MEMCPY (Subtable->LengthField, &Subtable->TotalLength, 383a88e22b7SJung-uk Kim Subtable->SizeOfLengthField); 384a88e22b7SJung-uk Kim } 385