rscreate.c revision 73561
119370Spst/******************************************************************************* 298944Sobrien * 398944Sobrien * Module Name: rscreate - AcpiRsCreateResourceList 419370Spst * AcpiRsCreatePciRoutingTable 519370Spst * AcpiRsCreateByteStream 619370Spst * $Revision: 25 $ 798944Sobrien * 819370Spst ******************************************************************************/ 998944Sobrien 1098944Sobrien/****************************************************************************** 1198944Sobrien * 1298944Sobrien * 1. Copyright Notice 1319370Spst * 1498944Sobrien * Some or all of this work - Copyright (c) 1999, 2000, 2001, Intel Corp. 1598944Sobrien * All rights reserved. 1698944Sobrien * 1798944Sobrien * 2. License 1819370Spst * 1998944Sobrien * 2.1. This is your license from Intel Corp. under its intellectual property 2098944Sobrien * rights. You may have additional license terms from the party that provided 2198944Sobrien * you this software, covering your right to use that party's intellectual 2298944Sobrien * property rights. 2319370Spst * 2498944Sobrien * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 2519370Spst * copy of the source code appearing in this file ("Covered Code") an 2698944Sobrien * irrevocable, perpetual, worldwide license under Intel's copyrights in the 2719370Spst * base code distributed originally by Intel ("Original Intel Code") to copy, 2898944Sobrien * make derivatives, distribute, use and display any portion of the Covered 2998944Sobrien * Code in any form, with the right to sublicense such rights; and 3019370Spst * 3198944Sobrien * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 3298944Sobrien * license (with the right to sublicense), under only those claims of Intel 3398944Sobrien * patents that are infringed by the Original Intel Code, to make, use, sell, 3419370Spst * offer to sell, and import the Covered Code and derivative works thereof 3598944Sobrien * solely to the minimum extent necessary to exercise the above copyright 3619370Spst * license, and in no event shall the patent license extend to any additions 3719370Spst * to or modifications of the Original Intel Code. No other license or right 3898944Sobrien * is granted directly or by implication, estoppel or otherwise; 3998944Sobrien * 4098944Sobrien * The above copyright and patent license is granted only if the following 4198944Sobrien * conditions are met: 4298944Sobrien * 4319370Spst * 3. Conditions 4419370Spst * 4598944Sobrien * 3.1. Redistribution of Source with Rights to Further Distribute Source. 4698944Sobrien * Redistribution of source code of any substantial portion of the Covered 4798944Sobrien * Code or modification with rights to further distribute source must include 4898944Sobrien * the above Copyright Notice, the above License, this list of Conditions, 4998944Sobrien * and the following Disclaimer and Export Compliance provision. In addition, 5098944Sobrien * Licensee must cause all Covered Code to which Licensee contributes to 5198944Sobrien * contain a file documenting the changes Licensee made to create that Covered 5298944Sobrien * Code and the date of any change. Licensee must include in that file the 5398944Sobrien * documentation of any changes made by any predecessor Licensee. Licensee 5498944Sobrien * must include a prominent statement that the modification is derived, 5519370Spst * directly or indirectly, from Original Intel Code. 5698944Sobrien * 5719370Spst * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 5898944Sobrien * Redistribution of source code of any substantial portion of the Covered 5919370Spst * Code or modification without rights to further distribute source must 6098944Sobrien * include the following Disclaimer and Export Compliance provision in the 6198944Sobrien * documentation and/or other materials provided with distribution. In 6298944Sobrien * addition, Licensee may not authorize further sublicense of source of any 6319370Spst * portion of the Covered Code, and must include terms to the effect that the 6498944Sobrien * license from Licensee to its licensee is limited to the intellectual 6519370Spst * property embodied in the software Licensee provides to its licensee, and 6698944Sobrien * not to intellectual property embodied in modifications its licensee may 6719370Spst * make. 6819370Spst * 6998944Sobrien * 3.3. Redistribution of Executable. Redistribution in executable form of any 7098944Sobrien * substantial portion of the Covered Code or modification must reproduce the 7198944Sobrien * above Copyright Notice, and the following Disclaimer and Export Compliance 7219370Spst * provision in the documentation and/or other materials provided with the 7319370Spst * distribution. 7419370Spst * 7519370Spst * 3.4. Intel retains all right, title, and interest in and to the Original 7619370Spst * Intel Code. 7798944Sobrien * 7898944Sobrien * 3.5. Neither the name Intel nor any other trademark owned or controlled by 7998944Sobrien * Intel shall be used in advertising or otherwise to promote the sale, use or 8019370Spst * other dealings in products derived from or relating to the Covered Code 8119370Spst * without prior written authorization from Intel. 8219370Spst * 8319370Spst * 4. Disclaimer and Export Compliance 8498944Sobrien * 8598944Sobrien * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 8619370Spst * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 8798944Sobrien * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 8819370Spst * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 8998944Sobrien * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 9019370Spst * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 9198944Sobrien * PARTICULAR PURPOSE. 9219370Spst * 9398944Sobrien * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 9419370Spst * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 9519370Spst * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 9619370Spst * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 9719370Spst * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 9819370Spst * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 99 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 100 * LIMITED REMEDY. 101 * 102 * 4.3. Licensee shall not export, either directly or indirectly, any of this 103 * software or system incorporating such software without first obtaining any 104 * required license or other approval from the U. S. Department of Commerce or 105 * any other agency or department of the United States Government. In the 106 * event Licensee exports any such software from the United States or 107 * re-exports any such software from a foreign destination, Licensee shall 108 * ensure that the distribution and export/re-export of the software is in 109 * compliance with all laws, regulations, orders, or other restrictions of the 110 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 111 * any of its subsidiaries will export/re-export any technical data, process, 112 * software, or service, directly or indirectly, to any country for which the 113 * United States government or any agency thereof requires an export license, 114 * other governmental approval, or letter of assurance, without first obtaining 115 * such license, approval or letter. 116 * 117 *****************************************************************************/ 118 119 120#define __RSCREATE_C__ 121 122#include "acpi.h" 123#include "acresrc.h" 124#include "amlcode.h" 125#include "acnamesp.h" 126 127#define _COMPONENT RESOURCE_MANAGER 128 MODULE_NAME ("rscreate") 129 130 131/******************************************************************************* 132 * 133 * FUNCTION: AcpiRsCreateResourceList 134 * 135 * PARAMETERS: 136 * ByteStreamBuffer - Pointer to the resource byte stream 137 * OutputBuffer - Pointer to the user's buffer 138 * OutputBufferLength - Pointer to the size of OutputBuffer 139 * 140 * RETURN: Status - AE_OK if okay, else a valid ACPI_STATUS code 141 * If OutputBuffer is not large enough, OutputBufferLength 142 * indicates how large OutputBuffer should be, else it 143 * indicates how may UINT8 elements of OutputBuffer are valid. 144 * 145 * DESCRIPTION: Takes the byte stream returned from a _CRS, _PRS control method 146 * execution and parses the stream to create a linked list 147 * of device resources. 148 * 149 ******************************************************************************/ 150 151ACPI_STATUS 152AcpiRsCreateResourceList ( 153 ACPI_OPERAND_OBJECT *ByteStreamBuffer, 154 UINT8 *OutputBuffer, 155 UINT32 *OutputBufferLength) 156{ 157 158 ACPI_STATUS Status; 159 UINT8 *ByteStreamStart = NULL; 160 UINT32 ListSizeNeeded = 0; 161 UINT32 ByteStreamBufferLength = 0; 162 163 164 FUNCTION_TRACE ("RsCreateResourceList"); 165 166 167 DEBUG_PRINT (VERBOSE_INFO, ("RsCreateResourceList: ByteStreamBuffer = %p\n", 168 ByteStreamBuffer)); 169 170 /* 171 * Params already validated, so we don't re-validate here 172 */ 173 174 ByteStreamBufferLength = ByteStreamBuffer->Buffer.Length; 175 ByteStreamStart = ByteStreamBuffer->Buffer.Pointer; 176 177 /* 178 * Pass the ByteStreamBuffer into a module that can calculate 179 * the buffer size needed for the linked list 180 */ 181 Status = AcpiRsCalculateListLength (ByteStreamStart, 182 ByteStreamBufferLength, 183 &ListSizeNeeded); 184 185 DEBUG_PRINT (VERBOSE_INFO, 186 ("RsCreateResourceList: Status=%X ListSizeNeeded=%X\n", 187 Status, ListSizeNeeded)); 188 189 /* 190 * Exit with the error passed back 191 */ 192 if (ACPI_FAILURE (Status)) 193 { 194 return_ACPI_STATUS (Status); 195 } 196 197 /* 198 * If the linked list will fit into the available buffer 199 * call to fill in the list 200 */ 201 202 if (ListSizeNeeded <= *OutputBufferLength) 203 { 204 /* 205 * Zero out the return buffer before proceeding 206 */ 207 MEMSET (OutputBuffer, 0x00, *OutputBufferLength); 208 209 Status = AcpiRsByteStreamToList (ByteStreamStart, 210 ByteStreamBufferLength, 211 &OutputBuffer); 212 213 /* 214 * Exit with the error passed back 215 */ 216 if (ACPI_FAILURE (Status)) 217 { 218 return_ACPI_STATUS (Status); 219 } 220 221 DEBUG_PRINT (VERBOSE_INFO, ("RsByteStreamToList: OutputBuffer = %p\n", 222 OutputBuffer)); 223 } 224 225 else 226 { 227 *OutputBufferLength = ListSizeNeeded; 228 return_ACPI_STATUS (AE_BUFFER_OVERFLOW); 229 } 230 231 *OutputBufferLength = ListSizeNeeded; 232 return_ACPI_STATUS (AE_OK); 233 234} 235 236 237/******************************************************************************* 238 * 239 * FUNCTION: AcpiRsCreatePciRoutingTable 240 * 241 * PARAMETERS: 242 * PackageObject - Pointer to an ACPI_OPERAND_OBJECT 243 * package 244 * OutputBuffer - Pointer to the user's buffer 245 * OutputBufferLength - Size of OutputBuffer 246 * 247 * RETURN: Status AE_OK if okay, else a valid ACPI_STATUS code. 248 * If the OutputBuffer is too small, the error will be 249 * AE_BUFFER_OVERFLOW and OutputBufferLength will point 250 * to the size buffer needed. 251 * 252 * DESCRIPTION: Takes the ACPI_OPERAND_OBJECT package and creates a 253 * linked list of PCI interrupt descriptions 254 * 255 ******************************************************************************/ 256 257ACPI_STATUS 258AcpiRsCreatePciRoutingTable ( 259 ACPI_OPERAND_OBJECT *PackageObject, 260 UINT8 *OutputBuffer, 261 UINT32 *OutputBufferLength) 262{ 263 UINT8 *Buffer = OutputBuffer; 264 ACPI_OPERAND_OBJECT **TopObjectList = NULL; 265 ACPI_OPERAND_OBJECT **SubObjectList = NULL; 266 ACPI_OPERAND_OBJECT *PackageElement = NULL; 267 UINT32 BufferSizeNeeded = 0; 268 UINT32 NumberOfElements = 0; 269 UINT32 Index = 0; 270 PCI_ROUTING_TABLE *UserPrt = NULL; 271 ACPI_NAMESPACE_NODE *Node; 272 ACPI_STATUS Status; 273 274 275 FUNCTION_TRACE ("RsCreatePciRoutingTable"); 276 277 278 /* 279 * Params already validated, so we don't re-validate here 280 */ 281 282 Status = AcpiRsCalculatePciRoutingTableLength(PackageObject, 283 &BufferSizeNeeded); 284 285 DEBUG_PRINT (VERBOSE_INFO, 286 ("RsCreatePciRoutingTable: BufferSizeNeeded = %X\n", 287 BufferSizeNeeded)); 288 289 /* 290 * If the data will fit into the available buffer 291 * call to fill in the list 292 */ 293 if (BufferSizeNeeded <= *OutputBufferLength) 294 { 295 /* 296 * Zero out the return buffer before proceeding 297 */ 298 MEMSET (OutputBuffer, 0x00, *OutputBufferLength); 299 300 /* 301 * Loop through the ACPI_INTERNAL_OBJECTS - Each object should 302 * contain a UINT32 Address, a UINT8 Pin, a Name and a UINT8 303 * SourceIndex. 304 */ 305 TopObjectList = PackageObject->Package.Elements; 306 NumberOfElements = PackageObject->Package.Count; 307 UserPrt = (PCI_ROUTING_TABLE *) Buffer; 308 309 310 Buffer = ROUND_PTR_UP_TO_8 (Buffer, UINT8); 311 312 for (Index = 0; Index < NumberOfElements; Index++) 313 { 314 /* 315 * Point UserPrt past this current structure 316 * 317 * NOTE: On the first iteration, UserPrt->Length will 318 * be zero because we cleared the return buffer earlier 319 */ 320 Buffer += UserPrt->Length; 321 UserPrt = (PCI_ROUTING_TABLE *) Buffer; 322 323 324 /* 325 * Fill in the Length field with the information we 326 * have at this point. 327 * The minus four is to subtract the size of the 328 * UINT8 Source[4] member because it is added below. 329 */ 330 UserPrt->Length = (sizeof (PCI_ROUTING_TABLE) -4); 331 332 /* 333 * Dereference the sub-package 334 */ 335 PackageElement = *TopObjectList; 336 337 /* 338 * The SubObjectList will now point to an array of 339 * the four IRQ elements: Address, Pin, Source and 340 * SourceIndex 341 */ 342 SubObjectList = PackageElement->Package.Elements; 343 344 /* 345 * 1) First subobject: Dereference the Address 346 */ 347 if (ACPI_TYPE_INTEGER == (*SubObjectList)->Common.Type) 348 { 349 UserPrt->Address = (*SubObjectList)->Integer.Value; 350 } 351 352 else 353 { 354 DEBUG_PRINT (ACPI_ERROR, 355 ("CreatePciRoutingTable: Need Integer, found %s\n", 356 AcpiCmGetTypeName ((*SubObjectList)->Common.Type))); 357 return_ACPI_STATUS (AE_BAD_DATA); 358 } 359 360 /* 361 * 2) Second subobject: Dereference the Pin 362 */ 363 SubObjectList++; 364 365 if (ACPI_TYPE_INTEGER == (*SubObjectList)->Common.Type) 366 { 367 UserPrt->Pin = 368 (UINT32) (*SubObjectList)->Integer.Value; 369 } 370 371 else 372 { 373 DEBUG_PRINT (ACPI_ERROR, 374 ("CreatePciRoutingTable: Need Integer, found %s\n", 375 AcpiCmGetTypeName ((*SubObjectList)->Common.Type))); 376 return_ACPI_STATUS (AE_BAD_DATA); 377 } 378 379 /* 380 * 3) Third subobject: Dereference the Source Name 381 */ 382 SubObjectList++; 383 384 switch ((*SubObjectList)->Common.Type) 385 { 386 case INTERNAL_TYPE_REFERENCE: 387 if ((*SubObjectList)->Reference.OpCode != AML_NAMEPATH_OP) 388 { 389 DEBUG_PRINT (ACPI_ERROR, 390 ("CreatePciRoutingTable: Need name, found reference op %X\n", 391 (*SubObjectList)->Reference.OpCode)); 392 return_ACPI_STATUS (AE_BAD_DATA); 393 } 394 395 Node = (*SubObjectList)->Reference.Node; 396 397 /* TBD: use *remaining* length of the buffer! */ 398 399 Status = AcpiNsHandleToPathname ((ACPI_HANDLE *) Node, 400 OutputBufferLength, UserPrt->Source); 401 402 UserPrt->Length += STRLEN (UserPrt->Source) + 1; /* include null terminator */ 403 break; 404 405 406 case ACPI_TYPE_STRING: 407 408 STRCPY (UserPrt->Source, 409 (*SubObjectList)->String.Pointer); 410 411 /* 412 * Add to the Length field the length of the string 413 */ 414 UserPrt->Length += (*SubObjectList)->String.Length; 415 break; 416 417 418 case ACPI_TYPE_INTEGER: 419 /* 420 * If this is a number, then the Source Name 421 * is NULL, since the entire buffer was zeroed 422 * out, we can leave this alone. 423 */ 424 /* 425 * Add to the Length field the length of 426 * the UINT32 NULL 427 */ 428 UserPrt->Length += sizeof (UINT32); 429 break; 430 431 432 default: 433 DEBUG_PRINT (ACPI_ERROR, 434 ("CreatePciRoutingTable: Need Integer, found %s\n", 435 AcpiCmGetTypeName ((*SubObjectList)->Common.Type))); 436 return_ACPI_STATUS (AE_BAD_DATA); 437 break; 438 } 439 440 /* Now align the current length */ 441 442 UserPrt->Length = ROUND_UP_TO_64BITS (UserPrt->Length); 443 444 /* 445 * 4) Fourth subobject: Dereference the Source Index 446 */ 447 SubObjectList++; 448 449 if (ACPI_TYPE_INTEGER == (*SubObjectList)->Common.Type) 450 { 451 UserPrt->SourceIndex = 452 (UINT32) (*SubObjectList)->Integer.Value; 453 } 454 455 else 456 { 457 DEBUG_PRINT (ACPI_ERROR, 458 ("CreatePciRoutingTable: Need Integer, found %s\n", 459 AcpiCmGetTypeName ((*SubObjectList)->Common.Type))); 460 return_ACPI_STATUS (AE_BAD_DATA); 461 } 462 463 /* 464 * Point to the next ACPI_OPERAND_OBJECT 465 */ 466 TopObjectList++; 467 } 468 469 DEBUG_PRINT (VERBOSE_INFO, 470 ("RsCreatePciRoutingTable: OutputBuffer = %p\n", 471 OutputBuffer)); 472 } 473 474 else 475 { 476 *OutputBufferLength = BufferSizeNeeded; 477 478 return_ACPI_STATUS (AE_BUFFER_OVERFLOW); 479 } 480 481 /* 482 * Report the amount of buffer used 483 */ 484 *OutputBufferLength = BufferSizeNeeded; 485 486 return_ACPI_STATUS (AE_OK); 487} 488 489 490/******************************************************************************* 491 * 492 * FUNCTION: AcpiRsCreateByteStream 493 * 494 * PARAMETERS: 495 * LinkedListBuffer - Pointer to the resource linked list 496 * OutputBuffer - Pointer to the user's buffer 497 * OutputBufferLength - Size of OutputBuffer 498 * 499 * RETURN: Status AE_OK if okay, else a valid ACPI_STATUS code. 500 * If the OutputBuffer is too small, the error will be 501 * AE_BUFFER_OVERFLOW and OutputBufferLength will point 502 * to the size buffer needed. 503 * 504 * DESCRIPTION: Takes the linked list of device resources and 505 * creates a bytestream to be used as input for the 506 * _SRS control method. 507 * 508 ******************************************************************************/ 509 510ACPI_STATUS 511AcpiRsCreateByteStream ( 512 RESOURCE *LinkedListBuffer, 513 UINT8 *OutputBuffer, 514 UINT32 *OutputBufferLength) 515{ 516 ACPI_STATUS Status; 517 UINT32 ByteStreamSizeNeeded = 0; 518 519 520 FUNCTION_TRACE ("RsCreateByteStream"); 521 522 523 DEBUG_PRINT (VERBOSE_INFO, 524 ("RsCreateByteStream: LinkedListBuffer = %p\n", 525 LinkedListBuffer)); 526 527 /* 528 * Params already validated, so we don't re-validate here 529 * 530 * Pass the LinkedListBuffer into a module that can calculate 531 * the buffer size needed for the byte stream. 532 */ 533 Status = AcpiRsCalculateByteStreamLength (LinkedListBuffer, 534 &ByteStreamSizeNeeded); 535 536 DEBUG_PRINT (VERBOSE_INFO, 537 ("RsCreateByteStream: ByteStreamSizeNeeded=%X, %s\n", 538 ByteStreamSizeNeeded, 539 AcpiCmFormatException (Status))); 540 541 /* 542 * Exit with the error passed back 543 */ 544 if (ACPI_FAILURE (Status)) 545 { 546 return_ACPI_STATUS (Status); 547 } 548 549 /* 550 * If the linked list will fit into the available buffer 551 * call to fill in the list 552 */ 553 554 if (ByteStreamSizeNeeded <= *OutputBufferLength) 555 { 556 /* 557 * Zero out the return buffer before proceeding 558 */ 559 MEMSET (OutputBuffer, 0x00, *OutputBufferLength); 560 561 Status = AcpiRsListToByteStream (LinkedListBuffer, 562 ByteStreamSizeNeeded, 563 &OutputBuffer); 564 565 /* 566 * Exit with the error passed back 567 */ 568 if (ACPI_FAILURE (Status)) 569 { 570 return_ACPI_STATUS (Status); 571 } 572 573 DEBUG_PRINT (VERBOSE_INFO, 574 ("RsListToByteStream: OutputBuffer = %p\n", 575 OutputBuffer)); 576 } 577 else 578 { 579 *OutputBufferLength = ByteStreamSizeNeeded; 580 return_ACPI_STATUS (AE_BUFFER_OVERFLOW); 581 } 582 583 return_ACPI_STATUS (AE_OK); 584} 585 586