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 7*d244b227SJung-uk Kim /* 8*d244b227SJung-uk Kim * Copyright (C) 2000 - 2011, Intel Corp. 9a88e22b7SJung-uk Kim * All rights reserved. 10a88e22b7SJung-uk Kim * 11*d244b227SJung-uk Kim * Redistribution and use in source and binary forms, with or without 12*d244b227SJung-uk Kim * modification, are permitted provided that the following conditions 13*d244b227SJung-uk Kim * are met: 14*d244b227SJung-uk Kim * 1. Redistributions of source code must retain the above copyright 15*d244b227SJung-uk Kim * notice, this list of conditions, and the following disclaimer, 16*d244b227SJung-uk Kim * without modification. 17*d244b227SJung-uk Kim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18*d244b227SJung-uk Kim * substantially similar to the "NO WARRANTY" disclaimer below 19*d244b227SJung-uk Kim * ("Disclaimer") and any redistribution must be conditioned upon 20*d244b227SJung-uk Kim * including a substantially similar Disclaimer requirement for further 21*d244b227SJung-uk Kim * binary redistribution. 22*d244b227SJung-uk Kim * 3. Neither the names of the above-listed copyright holders nor the names 23*d244b227SJung-uk Kim * of any contributors may be used to endorse or promote products derived 24*d244b227SJung-uk Kim * from this software without specific prior written permission. 25a88e22b7SJung-uk Kim * 26*d244b227SJung-uk Kim * Alternatively, this software may be distributed under the terms of the 27*d244b227SJung-uk Kim * GNU General Public License ("GPL") version 2 as published by the Free 28*d244b227SJung-uk Kim * Software Foundation. 29a88e22b7SJung-uk Kim * 30*d244b227SJung-uk Kim * NO WARRANTY 31*d244b227SJung-uk Kim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32*d244b227SJung-uk Kim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33*d244b227SJung-uk Kim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34*d244b227SJung-uk Kim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35*d244b227SJung-uk Kim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36*d244b227SJung-uk Kim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37*d244b227SJung-uk Kim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38*d244b227SJung-uk Kim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39*d244b227SJung-uk Kim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40*d244b227SJung-uk Kim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41*d244b227SJung-uk Kim * POSSIBILITY OF SUCH DAMAGES. 42*d244b227SJung-uk Kim */ 43a88e22b7SJung-uk Kim 44a88e22b7SJung-uk Kim #define __DTSUBTABLE_C__ 45a88e22b7SJung-uk Kim 46a88e22b7SJung-uk Kim #include <contrib/dev/acpica/compiler/aslcompiler.h> 47a88e22b7SJung-uk Kim #include <contrib/dev/acpica/compiler/dtcompiler.h> 48a88e22b7SJung-uk Kim 49a88e22b7SJung-uk Kim #define _COMPONENT DT_COMPILER 50a88e22b7SJung-uk Kim ACPI_MODULE_NAME ("dtsubtable") 51a88e22b7SJung-uk Kim 52a88e22b7SJung-uk Kim 53a88e22b7SJung-uk Kim /****************************************************************************** 54a88e22b7SJung-uk Kim * 55a88e22b7SJung-uk Kim * FUNCTION: DtCreateSubtable 56a88e22b7SJung-uk Kim * 57a88e22b7SJung-uk Kim * PARAMETERS: Buffer - Input buffer 58a88e22b7SJung-uk Kim * Length - Buffer length 59a88e22b7SJung-uk Kim * RetSubtable - Returned newly created subtable 60a88e22b7SJung-uk Kim * 61a88e22b7SJung-uk Kim * RETURN: None 62a88e22b7SJung-uk Kim * 63a88e22b7SJung-uk Kim * DESCRIPTION: Create a subtable that is not listed with ACPI_DMTABLE_INFO 64a88e22b7SJung-uk Kim * For example, FACS has 24 bytes reserved at the end 65a88e22b7SJung-uk Kim * and it's not listed at AcpiDmTableInfoFacs 66a88e22b7SJung-uk Kim * 67a88e22b7SJung-uk Kim *****************************************************************************/ 68a88e22b7SJung-uk Kim 69a88e22b7SJung-uk Kim void 70a88e22b7SJung-uk Kim DtCreateSubtable ( 71a88e22b7SJung-uk Kim UINT8 *Buffer, 72a88e22b7SJung-uk Kim UINT32 Length, 73a88e22b7SJung-uk Kim DT_SUBTABLE **RetSubtable) 74a88e22b7SJung-uk Kim { 75a88e22b7SJung-uk Kim DT_SUBTABLE *Subtable; 76a88e22b7SJung-uk Kim 77a88e22b7SJung-uk Kim 78a88e22b7SJung-uk Kim Subtable = UtLocalCalloc (sizeof (DT_SUBTABLE)); 79a88e22b7SJung-uk Kim 80a88e22b7SJung-uk Kim /* Create a new buffer for the subtable data */ 81a88e22b7SJung-uk Kim 82a88e22b7SJung-uk Kim Subtable->Buffer = UtLocalCalloc (Length); 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; 115a88e22b7SJung-uk Kim 116a88e22b7SJung-uk Kim /* Link the new entry into the child list */ 117a88e22b7SJung-uk Kim 118a88e22b7SJung-uk Kim if (!ParentTable->Child) 119a88e22b7SJung-uk Kim { 120a88e22b7SJung-uk Kim ParentTable->Child = Subtable; 121a88e22b7SJung-uk Kim } 122a88e22b7SJung-uk Kim else 123a88e22b7SJung-uk Kim { 124a88e22b7SJung-uk Kim /* Walk to the end of the child list */ 125a88e22b7SJung-uk Kim 126a88e22b7SJung-uk Kim ChildTable = ParentTable->Child; 127a88e22b7SJung-uk Kim while (ChildTable->Peer) 128a88e22b7SJung-uk Kim { 129a88e22b7SJung-uk Kim ChildTable = ChildTable->Peer; 130a88e22b7SJung-uk Kim } 131a88e22b7SJung-uk Kim 132a88e22b7SJung-uk Kim /* Add new subtable at the end of the child list */ 133a88e22b7SJung-uk Kim 134a88e22b7SJung-uk Kim ChildTable->Peer = Subtable; 135a88e22b7SJung-uk Kim } 136a88e22b7SJung-uk Kim } 137a88e22b7SJung-uk Kim 138a88e22b7SJung-uk Kim 139a88e22b7SJung-uk Kim /****************************************************************************** 140a88e22b7SJung-uk Kim * 141a88e22b7SJung-uk Kim * FUNCTION: DtPushSubtable 142a88e22b7SJung-uk Kim * 143a88e22b7SJung-uk Kim * PARAMETERS: Subtable - Subtable to push 144a88e22b7SJung-uk Kim * 145a88e22b7SJung-uk Kim * RETURN: None 146a88e22b7SJung-uk Kim * 147a88e22b7SJung-uk Kim * DESCRIPTION: Push a subtable onto a subtable stack 148a88e22b7SJung-uk Kim * 149a88e22b7SJung-uk Kim *****************************************************************************/ 150a88e22b7SJung-uk Kim 151a88e22b7SJung-uk Kim void 152a88e22b7SJung-uk Kim DtPushSubtable ( 153a88e22b7SJung-uk Kim DT_SUBTABLE *Subtable) 154a88e22b7SJung-uk Kim { 155a88e22b7SJung-uk Kim 156a88e22b7SJung-uk Kim Subtable->StackTop = Gbl_SubtableStack; 157a88e22b7SJung-uk Kim Gbl_SubtableStack = Subtable; 158a88e22b7SJung-uk Kim } 159a88e22b7SJung-uk Kim 160a88e22b7SJung-uk Kim 161a88e22b7SJung-uk Kim /****************************************************************************** 162a88e22b7SJung-uk Kim * 163a88e22b7SJung-uk Kim * FUNCTION: DtPopSubtable 164a88e22b7SJung-uk Kim * 165a88e22b7SJung-uk Kim * PARAMETERS: None 166a88e22b7SJung-uk Kim * 167a88e22b7SJung-uk Kim * RETURN: None 168a88e22b7SJung-uk Kim * 169a88e22b7SJung-uk Kim * DESCRIPTION: Pop a subtable from a subtable stack. Uses global SubtableStack 170a88e22b7SJung-uk Kim * 171a88e22b7SJung-uk Kim *****************************************************************************/ 172a88e22b7SJung-uk Kim 173a88e22b7SJung-uk Kim void 174a88e22b7SJung-uk Kim DtPopSubtable ( 175a88e22b7SJung-uk Kim void) 176a88e22b7SJung-uk Kim { 177a88e22b7SJung-uk Kim DT_SUBTABLE *Subtable; 178a88e22b7SJung-uk Kim 179a88e22b7SJung-uk Kim 180a88e22b7SJung-uk Kim Subtable = Gbl_SubtableStack; 181a88e22b7SJung-uk Kim 182a88e22b7SJung-uk Kim if (Subtable) 183a88e22b7SJung-uk Kim { 184a88e22b7SJung-uk Kim Gbl_SubtableStack = Subtable->StackTop; 185a88e22b7SJung-uk Kim } 186a88e22b7SJung-uk Kim } 187a88e22b7SJung-uk Kim 188a88e22b7SJung-uk Kim 189a88e22b7SJung-uk Kim /****************************************************************************** 190a88e22b7SJung-uk Kim * 191a88e22b7SJung-uk Kim * FUNCTION: DtPeekSubtable 192a88e22b7SJung-uk Kim * 193a88e22b7SJung-uk Kim * PARAMETERS: None 194a88e22b7SJung-uk Kim * 195a88e22b7SJung-uk Kim * RETURN: The subtable on top of stack 196a88e22b7SJung-uk Kim * 197a88e22b7SJung-uk Kim * DESCRIPTION: Get the subtable on top of stack 198a88e22b7SJung-uk Kim * 199a88e22b7SJung-uk Kim *****************************************************************************/ 200a88e22b7SJung-uk Kim 201a88e22b7SJung-uk Kim DT_SUBTABLE * 202a88e22b7SJung-uk Kim DtPeekSubtable ( 203a88e22b7SJung-uk Kim void) 204a88e22b7SJung-uk Kim { 205a88e22b7SJung-uk Kim 206a88e22b7SJung-uk Kim return (Gbl_SubtableStack); 207a88e22b7SJung-uk Kim } 208a88e22b7SJung-uk Kim 209a88e22b7SJung-uk Kim 210a88e22b7SJung-uk Kim /****************************************************************************** 211a88e22b7SJung-uk Kim * 212a88e22b7SJung-uk Kim * FUNCTION: DtGetNextSubtable 213a88e22b7SJung-uk Kim * 214a88e22b7SJung-uk Kim * PARAMETERS: ParentTable - Parent table whose children we are 215a88e22b7SJung-uk Kim * getting 216a88e22b7SJung-uk Kim * ChildTable - Previous child that was found. 217a88e22b7SJung-uk Kim * The NEXT child will be returned 218a88e22b7SJung-uk Kim * 219a88e22b7SJung-uk Kim * RETURN: Pointer to the NEXT child or NULL if none is found. 220a88e22b7SJung-uk Kim * 221a88e22b7SJung-uk Kim * DESCRIPTION: Return the next peer subtable within the tree. 222a88e22b7SJung-uk Kim * 223a88e22b7SJung-uk Kim *****************************************************************************/ 224a88e22b7SJung-uk Kim 225a88e22b7SJung-uk Kim DT_SUBTABLE * 226a88e22b7SJung-uk Kim DtGetNextSubtable ( 227a88e22b7SJung-uk Kim DT_SUBTABLE *ParentTable, 228a88e22b7SJung-uk Kim DT_SUBTABLE *ChildTable) 229a88e22b7SJung-uk Kim { 230a88e22b7SJung-uk Kim ACPI_FUNCTION_ENTRY (); 231a88e22b7SJung-uk Kim 232a88e22b7SJung-uk Kim 233a88e22b7SJung-uk Kim if (!ChildTable) 234a88e22b7SJung-uk Kim { 235a88e22b7SJung-uk Kim /* It's really the parent's _scope_ that we want */ 236a88e22b7SJung-uk Kim 237a88e22b7SJung-uk Kim return (ParentTable->Child); 238a88e22b7SJung-uk Kim } 239a88e22b7SJung-uk Kim 240a88e22b7SJung-uk Kim /* Otherwise just return the next peer (NULL if at end-of-list) */ 241a88e22b7SJung-uk Kim 242a88e22b7SJung-uk Kim return (ChildTable->Peer); 243a88e22b7SJung-uk Kim } 244a88e22b7SJung-uk Kim 245a88e22b7SJung-uk Kim 246a88e22b7SJung-uk Kim /****************************************************************************** 247a88e22b7SJung-uk Kim * 248a88e22b7SJung-uk Kim * FUNCTION: DtGetParentSubtable 249a88e22b7SJung-uk Kim * 250a88e22b7SJung-uk Kim * PARAMETERS: Subtable - Current subtable 251a88e22b7SJung-uk Kim * 252a88e22b7SJung-uk Kim * RETURN: Parent of the given subtable 253a88e22b7SJung-uk Kim * 254a88e22b7SJung-uk Kim * DESCRIPTION: Get the parent of the given subtable in the tree 255a88e22b7SJung-uk Kim * 256a88e22b7SJung-uk Kim *****************************************************************************/ 257a88e22b7SJung-uk Kim 258a88e22b7SJung-uk Kim DT_SUBTABLE * 259a88e22b7SJung-uk Kim DtGetParentSubtable ( 260a88e22b7SJung-uk Kim DT_SUBTABLE *Subtable) 261a88e22b7SJung-uk Kim { 262a88e22b7SJung-uk Kim 263a88e22b7SJung-uk Kim if (!Subtable) 264a88e22b7SJung-uk Kim { 265a88e22b7SJung-uk Kim return (NULL); 266a88e22b7SJung-uk Kim } 267a88e22b7SJung-uk Kim 268a88e22b7SJung-uk Kim return (Subtable->Parent); 269a88e22b7SJung-uk Kim } 270a88e22b7SJung-uk Kim 271a88e22b7SJung-uk Kim 272a88e22b7SJung-uk Kim /****************************************************************************** 273a88e22b7SJung-uk Kim * 274a88e22b7SJung-uk Kim * FUNCTION: DtGetSubtableLength 275a88e22b7SJung-uk Kim * 276a88e22b7SJung-uk Kim * PARAMETERS: Field - Current field list pointer 277a88e22b7SJung-uk Kim * Info - Data table info 278a88e22b7SJung-uk Kim * 279a88e22b7SJung-uk Kim * RETURN: Subtable length 280a88e22b7SJung-uk Kim * 281a88e22b7SJung-uk Kim * DESCRIPTION: Get length of bytes needed to compile the subtable 282a88e22b7SJung-uk Kim * 283a88e22b7SJung-uk Kim *****************************************************************************/ 284a88e22b7SJung-uk Kim 285a88e22b7SJung-uk Kim UINT32 286a88e22b7SJung-uk Kim DtGetSubtableLength ( 287a88e22b7SJung-uk Kim DT_FIELD *Field, 288a88e22b7SJung-uk Kim ACPI_DMTABLE_INFO *Info) 289a88e22b7SJung-uk Kim { 290a88e22b7SJung-uk Kim UINT32 ByteLength = 0; 291a88e22b7SJung-uk Kim 292a88e22b7SJung-uk Kim 293a88e22b7SJung-uk Kim /* Walk entire Info table; Null name terminates */ 294a88e22b7SJung-uk Kim 295a88e22b7SJung-uk Kim for (; Info->Name; Info++) 296a88e22b7SJung-uk Kim { 297a88e22b7SJung-uk Kim ByteLength += DtGetFieldLength (Field, Info); 298a88e22b7SJung-uk Kim } 299a88e22b7SJung-uk Kim 300a88e22b7SJung-uk Kim return (ByteLength); 301a88e22b7SJung-uk Kim } 302a88e22b7SJung-uk Kim 303a88e22b7SJung-uk Kim 304a88e22b7SJung-uk Kim /****************************************************************************** 305a88e22b7SJung-uk Kim * 306a88e22b7SJung-uk Kim * FUNCTION: DtSetSubtableLength 307a88e22b7SJung-uk Kim * 308a88e22b7SJung-uk Kim * PARAMETERS: Subtable - Subtable 309a88e22b7SJung-uk Kim * 310a88e22b7SJung-uk Kim * RETURN: None 311a88e22b7SJung-uk Kim * 312a88e22b7SJung-uk Kim * DESCRIPTION: Set length of the subtable into its length field 313a88e22b7SJung-uk Kim * 314a88e22b7SJung-uk Kim *****************************************************************************/ 315a88e22b7SJung-uk Kim 316a88e22b7SJung-uk Kim void 317a88e22b7SJung-uk Kim DtSetSubtableLength ( 318a88e22b7SJung-uk Kim DT_SUBTABLE *Subtable) 319a88e22b7SJung-uk Kim { 320a88e22b7SJung-uk Kim 321a88e22b7SJung-uk Kim if (!Subtable->LengthField) 322a88e22b7SJung-uk Kim { 323a88e22b7SJung-uk Kim return; 324a88e22b7SJung-uk Kim } 325a88e22b7SJung-uk Kim 326a88e22b7SJung-uk Kim ACPI_MEMCPY (Subtable->LengthField, &Subtable->TotalLength, 327a88e22b7SJung-uk Kim Subtable->SizeOfLengthField); 328a88e22b7SJung-uk Kim } 329