dtsubtable.c revision 250838
190075Sobrien/****************************************************************************** 2132718Skan * 390075Sobrien * Module Name: dtsubtable.c - handling of subtables within ACPI tables 490075Sobrien * 590075Sobrien *****************************************************************************/ 690075Sobrien 790075Sobrien/* 890075Sobrien * Copyright (C) 2000 - 2013, Intel Corp. 990075Sobrien * All rights reserved. 1090075Sobrien * 1190075Sobrien * Redistribution and use in source and binary forms, with or without 1290075Sobrien * modification, are permitted provided that the following conditions 1390075Sobrien * are met: 1490075Sobrien * 1. Redistributions of source code must retain the above copyright 1590075Sobrien * notice, this list of conditions, and the following disclaimer, 1690075Sobrien * without modification. 1790075Sobrien * 2. Redistributions in binary form must reproduce at minimum a disclaimer 1890075Sobrien * substantially similar to the "NO WARRANTY" disclaimer below 1990075Sobrien * ("Disclaimer") and any redistribution must be conditioned upon 2090075Sobrien * including a substantially similar Disclaimer requirement for further 2190075Sobrien * binary redistribution. 2290075Sobrien * 3. Neither the names of the above-listed copyright holders nor the names 2390075Sobrien * of any contributors may be used to endorse or promote products derived 24117395Skan * from this software without specific prior written permission. 2590075Sobrien * 2690075Sobrien * Alternatively, this software may be distributed under the terms of the 2790075Sobrien * GNU General Public License ("GPL") version 2 as published by the Free 2890075Sobrien * Software Foundation. 2990075Sobrien * 3090075Sobrien * NO WARRANTY 3190075Sobrien * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3290075Sobrien * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3390075Sobrien * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 3490075Sobrien * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3590075Sobrien * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3690075Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3790075Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3890075Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 3990075Sobrien * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 4090075Sobrien * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 4190075Sobrien * POSSIBILITY OF SUCH DAMAGES. 4290075Sobrien */ 4390075Sobrien 4490075Sobrien#define __DTSUBTABLE_C__ 4590075Sobrien 4690075Sobrien#include <contrib/dev/acpica/compiler/aslcompiler.h> 4790075Sobrien#include <contrib/dev/acpica/compiler/dtcompiler.h> 4890075Sobrien 4990075Sobrien#define _COMPONENT DT_COMPILER 5090075Sobrien ACPI_MODULE_NAME ("dtsubtable") 5190075Sobrien 52117395Skan 53117395Skan/****************************************************************************** 54117395Skan * 5590075Sobrien * FUNCTION: DtCreateSubtable 5690075Sobrien * 5790075Sobrien * PARAMETERS: Buffer - Input buffer 5890075Sobrien * Length - Buffer length 5990075Sobrien * RetSubtable - Returned newly created subtable 6090075Sobrien * 6190075Sobrien * RETURN: None 6290075Sobrien * 6390075Sobrien * DESCRIPTION: Create a subtable that is not listed with ACPI_DMTABLE_INFO 6490075Sobrien * For example, FACS has 24 bytes reserved at the end 6590075Sobrien * and it's not listed at AcpiDmTableInfoFacs 6690075Sobrien * 6790075Sobrien *****************************************************************************/ 6890075Sobrien 6990075Sobrienvoid 7090075SobrienDtCreateSubtable ( 7190075Sobrien UINT8 *Buffer, 7290075Sobrien UINT32 Length, 7390075Sobrien DT_SUBTABLE **RetSubtable) 7490075Sobrien{ 7590075Sobrien DT_SUBTABLE *Subtable; 7690075Sobrien 7790075Sobrien 7890075Sobrien Subtable = UtLocalCalloc (sizeof (DT_SUBTABLE)); 79132718Skan 80132718Skan /* Create a new buffer for the subtable data */ 8190075Sobrien 8290075Sobrien Subtable->Buffer = UtLocalCalloc (Length); 8390075Sobrien ACPI_MEMCPY (Subtable->Buffer, Buffer, Length); 8490075Sobrien 8590075Sobrien Subtable->Length = Length; 8690075Sobrien Subtable->TotalLength = Length; 87117395Skan 88117395Skan *RetSubtable = Subtable; 8990075Sobrien} 9090075Sobrien 91132718Skan 92117395Skan/****************************************************************************** 93117395Skan * 94117395Skan * FUNCTION: DtInsertSubtable 95 * 96 * PARAMETERS: ParentTable - The Parent of the new subtable 97 * Subtable - The new subtable to insert 98 * 99 * RETURN: None 100 * 101 * DESCRIPTION: Insert the new subtable to the parent table 102 * 103 *****************************************************************************/ 104 105void 106DtInsertSubtable ( 107 DT_SUBTABLE *ParentTable, 108 DT_SUBTABLE *Subtable) 109{ 110 DT_SUBTABLE *ChildTable; 111 112 113 Subtable->Peer = NULL; 114 Subtable->Parent = ParentTable; 115 Subtable->Depth = ParentTable->Depth + 1; 116 117 /* Link the new entry into the child list */ 118 119 if (!ParentTable->Child) 120 { 121 ParentTable->Child = Subtable; 122 } 123 else 124 { 125 /* Walk to the end of the child list */ 126 127 ChildTable = ParentTable->Child; 128 while (ChildTable->Peer) 129 { 130 ChildTable = ChildTable->Peer; 131 } 132 133 /* Add new subtable at the end of the child list */ 134 135 ChildTable->Peer = Subtable; 136 } 137} 138 139 140/****************************************************************************** 141 * 142 * FUNCTION: DtPushSubtable 143 * 144 * PARAMETERS: Subtable - Subtable to push 145 * 146 * RETURN: None 147 * 148 * DESCRIPTION: Push a subtable onto a subtable stack 149 * 150 *****************************************************************************/ 151 152void 153DtPushSubtable ( 154 DT_SUBTABLE *Subtable) 155{ 156 157 Subtable->StackTop = Gbl_SubtableStack; 158 Gbl_SubtableStack = Subtable; 159} 160 161 162/****************************************************************************** 163 * 164 * FUNCTION: DtPopSubtable 165 * 166 * PARAMETERS: None 167 * 168 * RETURN: None 169 * 170 * DESCRIPTION: Pop a subtable from a subtable stack. Uses global SubtableStack 171 * 172 *****************************************************************************/ 173 174void 175DtPopSubtable ( 176 void) 177{ 178 DT_SUBTABLE *Subtable; 179 180 181 Subtable = Gbl_SubtableStack; 182 183 if (Subtable) 184 { 185 Gbl_SubtableStack = Subtable->StackTop; 186 } 187} 188 189 190/****************************************************************************** 191 * 192 * FUNCTION: DtPeekSubtable 193 * 194 * PARAMETERS: None 195 * 196 * RETURN: The subtable on top of stack 197 * 198 * DESCRIPTION: Get the subtable on top of stack 199 * 200 *****************************************************************************/ 201 202DT_SUBTABLE * 203DtPeekSubtable ( 204 void) 205{ 206 207 return (Gbl_SubtableStack); 208} 209 210 211/****************************************************************************** 212 * 213 * FUNCTION: DtGetNextSubtable 214 * 215 * PARAMETERS: ParentTable - Parent table whose children we are 216 * getting 217 * ChildTable - Previous child that was found. 218 * The NEXT child will be returned 219 * 220 * RETURN: Pointer to the NEXT child or NULL if none is found. 221 * 222 * DESCRIPTION: Return the next peer subtable within the tree. 223 * 224 *****************************************************************************/ 225 226DT_SUBTABLE * 227DtGetNextSubtable ( 228 DT_SUBTABLE *ParentTable, 229 DT_SUBTABLE *ChildTable) 230{ 231 ACPI_FUNCTION_ENTRY (); 232 233 234 if (!ChildTable) 235 { 236 /* It's really the parent's _scope_ that we want */ 237 238 return (ParentTable->Child); 239 } 240 241 /* Otherwise just return the next peer (NULL if at end-of-list) */ 242 243 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 316 Step = 5; 317 break; 318 319 case ACPI_DMT_HESTNTFY: 320 321 Step = 9; 322 break; 323 324 default: 325 326 Step = 1; 327 break; 328 } 329 330 for (i = 0; i < Step; i++) 331 { 332 if (!Field) 333 { 334 goto Error; 335 } 336 337 Field = Field->Next; 338 } 339 } 340 341 return (ByteLength); 342 343Error: 344 if (!Field) 345 { 346 sprintf (MsgBuffer, "Found NULL field - Field name \"%s\" needed", 347 Info->Name); 348 DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer); 349 } 350 351 return (ASL_EOF); 352} 353 354 355/****************************************************************************** 356 * 357 * FUNCTION: DtSetSubtableLength 358 * 359 * PARAMETERS: Subtable - Subtable 360 * 361 * RETURN: None 362 * 363 * DESCRIPTION: Set length of the subtable into its length field 364 * 365 *****************************************************************************/ 366 367void 368DtSetSubtableLength ( 369 DT_SUBTABLE *Subtable) 370{ 371 372 if (!Subtable->LengthField) 373 { 374 return; 375 } 376 377 ACPI_MEMCPY (Subtable->LengthField, &Subtable->TotalLength, 378 Subtable->SizeOfLengthField); 379} 380