rsirq.c revision 91116
1/******************************************************************************* 2 * 3 * Module Name: rsirq - IRQ resource descriptors 4 * $Revision: 24 $ 5 * 6 ******************************************************************************/ 7 8/****************************************************************************** 9 * 10 * 1. Copyright Notice 11 * 12 * Some or all of this work - Copyright (c) 1999 - 2002, Intel Corp. 13 * All rights reserved. 14 * 15 * 2. License 16 * 17 * 2.1. This is your license from Intel Corp. under its intellectual property 18 * rights. You may have additional license terms from the party that provided 19 * you this software, covering your right to use that party's intellectual 20 * property rights. 21 * 22 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 23 * copy of the source code appearing in this file ("Covered Code") an 24 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 25 * base code distributed originally by Intel ("Original Intel Code") to copy, 26 * make derivatives, distribute, use and display any portion of the Covered 27 * Code in any form, with the right to sublicense such rights; and 28 * 29 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 30 * license (with the right to sublicense), under only those claims of Intel 31 * patents that are infringed by the Original Intel Code, to make, use, sell, 32 * offer to sell, and import the Covered Code and derivative works thereof 33 * solely to the minimum extent necessary to exercise the above copyright 34 * license, and in no event shall the patent license extend to any additions 35 * to or modifications of the Original Intel Code. No other license or right 36 * is granted directly or by implication, estoppel or otherwise; 37 * 38 * The above copyright and patent license is granted only if the following 39 * conditions are met: 40 * 41 * 3. Conditions 42 * 43 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 44 * Redistribution of source code of any substantial portion of the Covered 45 * Code or modification with rights to further distribute source must include 46 * the above Copyright Notice, the above License, this list of Conditions, 47 * and the following Disclaimer and Export Compliance provision. In addition, 48 * Licensee must cause all Covered Code to which Licensee contributes to 49 * contain a file documenting the changes Licensee made to create that Covered 50 * Code and the date of any change. Licensee must include in that file the 51 * documentation of any changes made by any predecessor Licensee. Licensee 52 * must include a prominent statement that the modification is derived, 53 * directly or indirectly, from Original Intel Code. 54 * 55 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 56 * Redistribution of source code of any substantial portion of the Covered 57 * Code or modification without rights to further distribute source must 58 * include the following Disclaimer and Export Compliance provision in the 59 * documentation and/or other materials provided with distribution. In 60 * addition, Licensee may not authorize further sublicense of source of any 61 * portion of the Covered Code, and must include terms to the effect that the 62 * license from Licensee to its licensee is limited to the intellectual 63 * property embodied in the software Licensee provides to its licensee, and 64 * not to intellectual property embodied in modifications its licensee may 65 * make. 66 * 67 * 3.3. Redistribution of Executable. Redistribution in executable form of any 68 * substantial portion of the Covered Code or modification must reproduce the 69 * above Copyright Notice, and the following Disclaimer and Export Compliance 70 * provision in the documentation and/or other materials provided with the 71 * distribution. 72 * 73 * 3.4. Intel retains all right, title, and interest in and to the Original 74 * Intel Code. 75 * 76 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 77 * Intel shall be used in advertising or otherwise to promote the sale, use or 78 * other dealings in products derived from or relating to the Covered Code 79 * without prior written authorization from Intel. 80 * 81 * 4. Disclaimer and Export Compliance 82 * 83 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 84 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 85 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 86 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 87 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 88 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 89 * PARTICULAR PURPOSE. 90 * 91 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 92 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 93 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 94 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 95 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 96 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 97 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 98 * LIMITED REMEDY. 99 * 100 * 4.3. Licensee shall not export, either directly or indirectly, any of this 101 * software or system incorporating such software without first obtaining any 102 * required license or other approval from the U. S. Department of Commerce or 103 * any other agency or department of the United States Government. In the 104 * event Licensee exports any such software from the United States or 105 * re-exports any such software from a foreign destination, Licensee shall 106 * ensure that the distribution and export/re-export of the software is in 107 * compliance with all laws, regulations, orders, or other restrictions of the 108 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 109 * any of its subsidiaries will export/re-export any technical data, process, 110 * software, or service, directly or indirectly, to any country for which the 111 * United States government or any agency thereof requires an export license, 112 * other governmental approval, or letter of assurance, without first obtaining 113 * such license, approval or letter. 114 * 115 *****************************************************************************/ 116 117#define __RSIRQ_C__ 118 119#include "acpi.h" 120#include "acresrc.h" 121 122#define _COMPONENT ACPI_RESOURCES 123 ACPI_MODULE_NAME ("rsirq") 124 125 126/******************************************************************************* 127 * 128 * FUNCTION: AcpiRsIrqResource 129 * 130 * PARAMETERS: ByteStreamBuffer - Pointer to the resource input byte 131 * stream 132 * BytesConsumed - Pointer to where the number of bytes 133 * consumed the ByteStreamBuffer is 134 * returned 135 * OutputBuffer - Pointer to the return data buffer 136 * StructureSize - Pointer to where the number of bytes 137 * in the return data struct is returned 138 * 139 * RETURN: Status 140 * 141 * DESCRIPTION: Take the resource byte stream and fill out the appropriate 142 * structure pointed to by the OutputBuffer. Return the 143 * number of bytes consumed from the byte stream. 144 * 145 ******************************************************************************/ 146 147ACPI_STATUS 148AcpiRsIrqResource ( 149 UINT8 *ByteStreamBuffer, 150 ACPI_SIZE *BytesConsumed, 151 UINT8 **OutputBuffer, 152 ACPI_SIZE *StructureSize) 153{ 154 UINT8 *Buffer = ByteStreamBuffer; 155 ACPI_RESOURCE *OutputStruct = (ACPI_RESOURCE *) *OutputBuffer; 156 UINT16 Temp16 = 0; 157 UINT8 Temp8 = 0; 158 UINT8 Index; 159 UINT8 i; 160 ACPI_SIZE StructSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_IRQ); 161 162 163 ACPI_FUNCTION_TRACE ("RsIrqResource"); 164 165 166 /* 167 * The number of bytes consumed are contained in the descriptor 168 * (Bits:0-1) 169 */ 170 Temp8 = *Buffer; 171 *BytesConsumed = (Temp8 & 0x03) + 1; 172 OutputStruct->Id = ACPI_RSTYPE_IRQ; 173 174 /* 175 * Point to the 16-bits of Bytes 1 and 2 176 */ 177 Buffer += 1; 178 ACPI_MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer); 179 180 OutputStruct->Data.Irq.NumberOfInterrupts = 0; 181 182 /* Decode the IRQ bits */ 183 184 for (i = 0, Index = 0; Index < 16; Index++) 185 { 186 if((Temp16 >> Index) & 0x01) 187 { 188 OutputStruct->Data.Irq.Interrupts[i] = Index; 189 i++; 190 } 191 } 192 OutputStruct->Data.Irq.NumberOfInterrupts = i; 193 194 /* 195 * Calculate the structure size based upon the number of interrupts 196 */ 197 StructSize += (OutputStruct->Data.Irq.NumberOfInterrupts - 1) * 4; 198 199 /* 200 * Point to Byte 3 if it is used 201 */ 202 if (4 == *BytesConsumed) 203 { 204 Buffer += 2; 205 Temp8 = *Buffer; 206 207 /* 208 * Check for HE, LL or HL 209 */ 210 if (Temp8 & 0x01) 211 { 212 OutputStruct->Data.Irq.EdgeLevel = ACPI_EDGE_SENSITIVE; 213 OutputStruct->Data.Irq.ActiveHighLow = ACPI_ACTIVE_HIGH; 214 } 215 else 216 { 217 if (Temp8 & 0x8) 218 { 219 OutputStruct->Data.Irq.EdgeLevel = ACPI_LEVEL_SENSITIVE; 220 OutputStruct->Data.Irq.ActiveHighLow = ACPI_ACTIVE_LOW; 221 } 222 else 223 { 224 /* 225 * Only _LL and _HE polarity/trigger interrupts 226 * are allowed (ACPI spec v1.0b ection 6.4.2.1), 227 * so an error will occur if we reach this point 228 */ 229 return_ACPI_STATUS (AE_BAD_DATA); 230 } 231 } 232 233 /* 234 * Check for sharable 235 */ 236 OutputStruct->Data.Irq.SharedExclusive = (Temp8 >> 3) & 0x01; 237 } 238 else 239 { 240 /* 241 * Assume Edge Sensitive, Active High, Non-Sharable 242 * per ACPI Specification 243 */ 244 OutputStruct->Data.Irq.EdgeLevel = ACPI_EDGE_SENSITIVE; 245 OutputStruct->Data.Irq.ActiveHighLow = ACPI_ACTIVE_HIGH; 246 OutputStruct->Data.Irq.SharedExclusive = ACPI_EXCLUSIVE; 247 } 248 249 /* 250 * Set the Length parameter 251 */ 252 OutputStruct->Length = StructSize; 253 254 /* 255 * Return the final size of the structure 256 */ 257 *StructureSize = StructSize; 258 return_ACPI_STATUS (AE_OK); 259} 260 261 262/******************************************************************************* 263 * 264 * FUNCTION: AcpiRsIrqStream 265 * 266 * PARAMETERS: LinkedList - Pointer to the resource linked list 267 * OutputBuffer - Pointer to the user's return buffer 268 * BytesConsumed - Pointer to where the number of bytes 269 * used in the OutputBuffer is returned 270 * 271 * RETURN: Status 272 * 273 * DESCRIPTION: Take the linked list resource structure and fills in the 274 * the appropriate bytes in a byte stream 275 * 276 ******************************************************************************/ 277 278ACPI_STATUS 279AcpiRsIrqStream ( 280 ACPI_RESOURCE *LinkedList, 281 UINT8 **OutputBuffer, 282 ACPI_SIZE *BytesConsumed) 283{ 284 UINT8 *Buffer = *OutputBuffer; 285 UINT16 Temp16 = 0; 286 UINT8 Temp8 = 0; 287 UINT8 Index; 288 BOOLEAN IRQInfoByteNeeded; 289 290 291 ACPI_FUNCTION_TRACE ("RsIrqStream"); 292 293 294 /* 295 * The descriptor field is set based upon whether a third byte is 296 * needed to contain the IRQ Information. 297 */ 298 if (ACPI_EDGE_SENSITIVE == LinkedList->Data.Irq.EdgeLevel && 299 ACPI_ACTIVE_HIGH == LinkedList->Data.Irq.ActiveHighLow && 300 ACPI_EXCLUSIVE == LinkedList->Data.Irq.SharedExclusive) 301 { 302 *Buffer = 0x22; 303 IRQInfoByteNeeded = FALSE; 304 } 305 else 306 { 307 *Buffer = 0x23; 308 IRQInfoByteNeeded = TRUE; 309 } 310 311 Buffer += 1; 312 Temp16 = 0; 313 314 /* 315 * Loop through all of the interrupts and set the mask bits 316 */ 317 for(Index = 0; 318 Index < LinkedList->Data.Irq.NumberOfInterrupts; 319 Index++) 320 { 321 Temp8 = (UINT8) LinkedList->Data.Irq.Interrupts[Index]; 322 Temp16 |= 0x1 << Temp8; 323 } 324 325 ACPI_MOVE_UNALIGNED16_TO_16 (Buffer, &Temp16); 326 Buffer += 2; 327 328 /* 329 * Set the IRQ Info byte if needed. 330 */ 331 if (IRQInfoByteNeeded) 332 { 333 Temp8 = 0; 334 Temp8 = (UINT8) ((LinkedList->Data.Irq.SharedExclusive & 335 0x01) << 4); 336 337 if (ACPI_LEVEL_SENSITIVE == LinkedList->Data.Irq.EdgeLevel && 338 ACPI_ACTIVE_LOW == LinkedList->Data.Irq.ActiveHighLow) 339 { 340 Temp8 |= 0x08; 341 } 342 else 343 { 344 Temp8 |= 0x01; 345 } 346 347 *Buffer = Temp8; 348 Buffer += 1; 349 } 350 351 /* 352 * Return the number of bytes consumed in this operation 353 */ 354 *BytesConsumed = ACPI_PTR_DIFF (Buffer, *OutputBuffer); 355 return_ACPI_STATUS (AE_OK); 356} 357 358 359/******************************************************************************* 360 * 361 * FUNCTION: AcpiRsExtendedIrqResource 362 * 363 * PARAMETERS: ByteStreamBuffer - Pointer to the resource input byte 364 * stream 365 * BytesConsumed - Pointer to where the number of bytes 366 * consumed the ByteStreamBuffer is 367 * returned 368 * OutputBuffer - Pointer to the return data buffer 369 * StructureSize - Pointer to where the number of bytes 370 * in the return data struct is returned 371 * 372 * RETURN: Status 373 * 374 * DESCRIPTION: Take the resource byte stream and fill out the appropriate 375 * structure pointed to by the OutputBuffer. Return the 376 * number of bytes consumed from the byte stream. 377 * 378 ******************************************************************************/ 379 380ACPI_STATUS 381AcpiRsExtendedIrqResource ( 382 UINT8 *ByteStreamBuffer, 383 ACPI_SIZE *BytesConsumed, 384 UINT8 **OutputBuffer, 385 ACPI_SIZE *StructureSize) 386{ 387 UINT8 *Buffer = ByteStreamBuffer; 388 ACPI_RESOURCE *OutputStruct = (ACPI_RESOURCE *) *OutputBuffer; 389 UINT16 Temp16 = 0; 390 UINT8 Temp8 = 0; 391 NATIVE_CHAR *TempPtr; 392 UINT8 Index; 393 ACPI_SIZE StructSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_EXT_IRQ); 394 395 396 ACPI_FUNCTION_TRACE ("RsExtendedIrqResource"); 397 398 399 /* 400 * Point past the Descriptor to get the number of bytes consumed 401 */ 402 Buffer += 1; 403 ACPI_MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer); 404 405 *BytesConsumed = Temp16 + 3; 406 OutputStruct->Id = ACPI_RSTYPE_EXT_IRQ; 407 408 /* 409 * Point to the Byte3 410 */ 411 Buffer += 2; 412 Temp8 = *Buffer; 413 414 OutputStruct->Data.ExtendedIrq.ProducerConsumer = Temp8 & 0x01; 415 416 /* 417 * Check for Interrupt Mode 418 * 419 * The definition of an Extended IRQ changed between ACPI spec v1.0b 420 * and ACPI spec 2.0 (section 6.4.3.6 in both). 421 * 422 * - Edge/Level are defined opposite in the table vs the headers 423 */ 424 OutputStruct->Data.ExtendedIrq.EdgeLevel = 425 (Temp8 & 0x2) ? ACPI_EDGE_SENSITIVE : ACPI_LEVEL_SENSITIVE; 426 427 /* 428 * Check Interrupt Polarity 429 */ 430 OutputStruct->Data.ExtendedIrq.ActiveHighLow = (Temp8 >> 2) & 0x1; 431 432 /* 433 * Check for sharable 434 */ 435 OutputStruct->Data.ExtendedIrq.SharedExclusive = (Temp8 >> 3) & 0x01; 436 437 /* 438 * Point to Byte4 (IRQ Table length) 439 */ 440 Buffer += 1; 441 Temp8 = *Buffer; 442 443 OutputStruct->Data.ExtendedIrq.NumberOfInterrupts = Temp8; 444 445 /* 446 * Add any additional structure size to properly calculate 447 * the next pointer at the end of this function 448 */ 449 StructSize += (Temp8 - 1) * 4; 450 451 /* 452 * Point to Byte5 (First IRQ Number) 453 */ 454 Buffer += 1; 455 456 /* 457 * Cycle through every IRQ in the table 458 */ 459 for (Index = 0; Index < Temp8; Index++) 460 { 461 OutputStruct->Data.ExtendedIrq.Interrupts[Index] = 462 (UINT32)*Buffer; 463 464 /* Point to the next IRQ */ 465 466 Buffer += 4; 467 } 468 469 /* 470 * This will leave us pointing to the Resource Source Index 471 * If it is present, then save it off and calculate the 472 * pointer to where the null terminated string goes: 473 * Each Interrupt takes 32-bits + the 5 bytes of the 474 * stream that are default. 475 */ 476 if (*BytesConsumed > 477 (UINT32)(OutputStruct->Data.ExtendedIrq.NumberOfInterrupts * 4) + 5) 478 { 479 /* Dereference the Index */ 480 481 Temp8 = *Buffer; 482 OutputStruct->Data.ExtendedIrq.ResourceSource.Index = (UINT32) Temp8; 483 484 /* Point to the String */ 485 486 Buffer += 1; 487 488 /* 489 * Point the String pointer to the end of this structure. 490 */ 491 OutputStruct->Data.ExtendedIrq.ResourceSource.StringPtr = 492 (NATIVE_CHAR *)(OutputStruct + StructSize); 493 494 TempPtr = OutputStruct->Data.ExtendedIrq.ResourceSource.StringPtr; 495 496 /* Copy the string into the buffer */ 497 498 Index = 0; 499 while (0x00 != *Buffer) 500 { 501 *TempPtr = *Buffer; 502 503 TempPtr += 1; 504 Buffer += 1; 505 Index += 1; 506 } 507 508 /* 509 * Add the terminating null 510 */ 511 *TempPtr = 0x00; 512 OutputStruct->Data.ExtendedIrq.ResourceSource.StringLength = Index + 1; 513 514 /* 515 * In order for the StructSize to fall on a 32-bit boundary, 516 * calculate the length of the string and expand the 517 * StructSize to the next 32-bit boundary. 518 */ 519 Temp8 = (UINT8) (Index + 1); 520 StructSize += ACPI_ROUND_UP_TO_32BITS (Temp8); 521 } 522 else 523 { 524 OutputStruct->Data.ExtendedIrq.ResourceSource.Index = 0x00; 525 OutputStruct->Data.ExtendedIrq.ResourceSource.StringLength = 0; 526 OutputStruct->Data.ExtendedIrq.ResourceSource.StringPtr = NULL; 527 } 528 529 /* 530 * Set the Length parameter 531 */ 532 OutputStruct->Length = StructSize; 533 534 /* 535 * Return the final size of the structure 536 */ 537 *StructureSize = StructSize; 538 return_ACPI_STATUS (AE_OK); 539} 540 541 542/******************************************************************************* 543 * 544 * FUNCTION: AcpiRsExtendedIrqStream 545 * 546 * PARAMETERS: LinkedList - Pointer to the resource linked list 547 * OutputBuffer - Pointer to the user's return buffer 548 * BytesConsumed - Pointer to where the number of bytes 549 * used in the OutputBuffer is returned 550 * 551 * RETURN: Status 552 * 553 * DESCRIPTION: Take the linked list resource structure and fills in the 554 * the appropriate bytes in a byte stream 555 * 556 ******************************************************************************/ 557 558ACPI_STATUS 559AcpiRsExtendedIrqStream ( 560 ACPI_RESOURCE *LinkedList, 561 UINT8 **OutputBuffer, 562 ACPI_SIZE *BytesConsumed) 563{ 564 UINT8 *Buffer = *OutputBuffer; 565 UINT16 *LengthField; 566 UINT8 Temp8 = 0; 567 UINT8 Index; 568 NATIVE_CHAR *TempPointer = NULL; 569 570 571 ACPI_FUNCTION_TRACE ("RsExtendedIrqStream"); 572 573 574 /* 575 * The descriptor field is static 576 */ 577 *Buffer = 0x89; 578 Buffer += 1; 579 580 /* 581 * Set a pointer to the Length field - to be filled in later 582 */ 583 LengthField = (UINT16 *)Buffer; 584 Buffer += 2; 585 586 /* 587 * Set the Interrupt vector flags 588 */ 589 Temp8 = (UINT8)(LinkedList->Data.ExtendedIrq.ProducerConsumer & 0x01); 590 Temp8 |= ((LinkedList->Data.ExtendedIrq.SharedExclusive & 0x01) << 3); 591 592 /* 593 * Set the Interrupt Mode 594 * 595 * The definition of an Extended IRQ changed between ACPI spec v1.0b 596 * and ACPI spec 2.0 (section 6.4.3.6 in both). This code does not 597 * implement the more restrictive definition of 1.0b 598 * 599 * - Edge/Level are defined opposite in the table vs the headers 600 */ 601 if (ACPI_EDGE_SENSITIVE == LinkedList->Data.ExtendedIrq.EdgeLevel) 602 { 603 Temp8 |= 0x2; 604 } 605 606 /* 607 * Set the Interrupt Polarity 608 */ 609 Temp8 |= ((LinkedList->Data.ExtendedIrq.ActiveHighLow & 0x1) << 2); 610 611 *Buffer = Temp8; 612 Buffer += 1; 613 614 /* 615 * Set the Interrupt table length 616 */ 617 Temp8 = (UINT8) LinkedList->Data.ExtendedIrq.NumberOfInterrupts; 618 619 *Buffer = Temp8; 620 Buffer += 1; 621 622 for (Index = 0; Index < LinkedList->Data.ExtendedIrq.NumberOfInterrupts; 623 Index++) 624 { 625 ACPI_MOVE_UNALIGNED32_TO_32 (Buffer, 626 &LinkedList->Data.ExtendedIrq.Interrupts[Index]); 627 Buffer += 4; 628 } 629 630 /* 631 * Resource Source Index and Resource Source are optional 632 */ 633 if (0 != LinkedList->Data.ExtendedIrq.ResourceSource.StringLength) 634 { 635 *Buffer = (UINT8) LinkedList->Data.ExtendedIrq.ResourceSource.Index; 636 Buffer += 1; 637 638 TempPointer = (NATIVE_CHAR *) Buffer; 639 640 /* 641 * Copy the string 642 */ 643 ACPI_STRCPY (TempPointer, 644 LinkedList->Data.ExtendedIrq.ResourceSource.StringPtr); 645 646 /* 647 * Buffer needs to be set to the length of the sting + one for the 648 * terminating null 649 */ 650 Buffer += (ACPI_STRLEN (LinkedList->Data.ExtendedIrq.ResourceSource.StringPtr) + 1); 651 } 652 653 /* 654 * Return the number of bytes consumed in this operation 655 */ 656 *BytesConsumed = ACPI_PTR_DIFF (Buffer, *OutputBuffer); 657 658 /* 659 * Set the length field to the number of bytes consumed 660 * minus the header size (3 bytes) 661 */ 662 *LengthField = (UINT16) (*BytesConsumed - 3); 663 return_ACPI_STATUS (AE_OK); 664} 665 666