1 /*******************************************************************************
3 * Module Name: rsmisc - Miscellaneous resource descriptors
5 ******************************************************************************/
8 * Copyright (C) 2000 - 2011, Intel Corp.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
46 #include <contrib/dev/acpica/include/acpi.h>
47 #include <contrib/dev/acpica/include/accommon.h>
48 #include <contrib/dev/acpica/include/acresrc.h>
50 #define _COMPONENT ACPI_RESOURCES
51 ACPI_MODULE_NAME ("rsmisc")
54 #define INIT_RESOURCE_TYPE(i) i->ResourceOffset
55 #define INIT_RESOURCE_LENGTH(i) i->AmlOffset
56 #define INIT_TABLE_LENGTH(i) i->Value
58 #define COMPARE_OPCODE(i) i->ResourceOffset
59 #define COMPARE_TARGET(i) i->AmlOffset
60 #define COMPARE_VALUE(i) i->Value
63 /*******************************************************************************
65 * FUNCTION: AcpiRsConvertAmlToResource
67 * PARAMETERS: Resource - Pointer to the resource descriptor
68 * Aml - Where the AML descriptor is returned
69 * Info - Pointer to appropriate conversion table
73 * DESCRIPTION: Convert an external AML resource descriptor to the corresponding
74 * internal resource descriptor
76 ******************************************************************************/
79 AcpiRsConvertAmlToResource (
80 ACPI_RESOURCE *Resource,
82 ACPI_RSCONVERT_INFO *Info)
84 ACPI_RS_LENGTH AmlResourceLength;
89 UINT8 FlagsMode = FALSE;
94 ACPI_FUNCTION_TRACE (RsConvertAmlToResource);
97 if (((ACPI_SIZE) Resource) & 0x3)
99 /* Each internal resource struct is expected to be 32-bit aligned */
101 ACPI_WARNING ((AE_INFO,
102 "Misaligned resource pointer (get): %p Type 0x%2.2X Length %u",
103 Resource, Resource->Type, Resource->Length));
106 /* Extract the resource Length field (does not include header length) */
108 AmlResourceLength = AcpiUtGetResourceLength (Aml);
111 * First table entry must be ACPI_RSC_INITxxx and must contain the
112 * table length (# of table entries)
114 Count = INIT_TABLE_LENGTH (Info);
119 * Source is the external AML byte stream buffer,
120 * destination is the internal resource descriptor
122 Source = ACPI_ADD_PTR (void, Aml, Info->AmlOffset);
123 Destination = ACPI_ADD_PTR (void, Resource, Info->ResourceOffset);
125 switch (Info->Opcode)
127 case ACPI_RSC_INITGET:
129 * Get the resource type and the initial (minimum) length
131 ACPI_MEMSET (Resource, 0, INIT_RESOURCE_LENGTH (Info));
132 Resource->Type = INIT_RESOURCE_TYPE (Info);
133 Resource->Length = INIT_RESOURCE_LENGTH (Info);
137 case ACPI_RSC_INITSET:
141 case ACPI_RSC_FLAGINIT:
147 case ACPI_RSC_1BITFLAG:
149 * Mask and shift the flag bit
151 ACPI_SET8 (Destination) = (UINT8)
152 ((ACPI_GET8 (Source) >> Info->Value) & 0x01);
156 case ACPI_RSC_2BITFLAG:
158 * Mask and shift the flag bits
160 ACPI_SET8 (Destination) = (UINT8)
161 ((ACPI_GET8 (Source) >> Info->Value) & 0x03);
167 ItemCount = ACPI_GET8 (Source);
168 ACPI_SET8 (Destination) = (UINT8) ItemCount;
170 Resource->Length = Resource->Length +
171 (Info->Value * (ItemCount - 1));
175 case ACPI_RSC_COUNT16:
177 ItemCount = AmlResourceLength;
178 ACPI_SET16 (Destination) = ItemCount;
180 Resource->Length = Resource->Length +
181 (Info->Value * (ItemCount - 1));
185 case ACPI_RSC_LENGTH:
187 Resource->Length = Resource->Length + Info->Value;
192 case ACPI_RSC_MOVE16:
193 case ACPI_RSC_MOVE32:
194 case ACPI_RSC_MOVE64:
196 * Raw data move. Use the Info value field unless ItemCount has
197 * been previously initialized via a COUNT opcode
201 ItemCount = Info->Value;
203 AcpiRsMoveData (Destination, Source, ItemCount, Info->Opcode);
209 ACPI_MEMSET (Destination, Info->AmlOffset, Info->Value);
215 Target = ACPI_ADD_PTR (char, Resource, Info->Value);
216 ACPI_MEMCPY (Destination, Source, ACPI_GET16 (Target));
220 case ACPI_RSC_ADDRESS:
222 * Common handler for address descriptor flags
224 if (!AcpiRsGetAddressCommon (Resource, Aml))
226 return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
231 case ACPI_RSC_SOURCE:
233 * Optional ResourceSource (Index and String)
236 AcpiRsGetResourceSource (AmlResourceLength, Info->Value,
237 Destination, Aml, NULL);
241 case ACPI_RSC_SOURCEX:
243 * Optional ResourceSource (Index and String). This is the more
244 * complicated case used by the Interrupt() macro
246 Target = ACPI_ADD_PTR (char, Resource, Info->AmlOffset + (ItemCount * 4));
249 AcpiRsGetResourceSource (AmlResourceLength,
250 (ACPI_RS_LENGTH) (((ItemCount - 1) * sizeof (UINT32)) + Info->Value),
251 Destination, Aml, Target);
255 case ACPI_RSC_BITMASK:
257 * 8-bit encoded bitmask (DMA macro)
259 ItemCount = AcpiRsDecodeBitmask (ACPI_GET8 (Source), Destination);
262 Resource->Length += (ItemCount - 1);
265 Target = ACPI_ADD_PTR (char, Resource, Info->Value);
266 ACPI_SET8 (Target) = (UINT8) ItemCount;
270 case ACPI_RSC_BITMASK16:
272 * 16-bit encoded bitmask (IRQ macro)
274 ACPI_MOVE_16_TO_16 (&Temp16, Source);
276 ItemCount = AcpiRsDecodeBitmask (Temp16, Destination);
279 Resource->Length += (ItemCount - 1);
282 Target = ACPI_ADD_PTR (char, Resource, Info->Value);
283 ACPI_SET8 (Target) = (UINT8) ItemCount;
287 case ACPI_RSC_EXIT_NE:
289 * Control - Exit conversion if not equal
291 switch (Info->ResourceOffset)
293 case ACPI_RSC_COMPARE_AML_LENGTH:
294 if (AmlResourceLength != Info->Value)
300 case ACPI_RSC_COMPARE_VALUE:
301 if (ACPI_GET8 (Source) != Info->Value)
309 ACPI_ERROR ((AE_INFO, "Invalid conversion sub-opcode"));
310 return_ACPI_STATUS (AE_BAD_PARAMETER);
317 ACPI_ERROR ((AE_INFO, "Invalid conversion opcode"));
318 return_ACPI_STATUS (AE_BAD_PARAMETER);
328 /* Round the resource struct length up to the next boundary (32 or 64) */
330 Resource->Length = (UINT32) ACPI_ROUND_UP_TO_NATIVE_WORD (Resource->Length);
332 return_ACPI_STATUS (AE_OK);
336 /*******************************************************************************
338 * FUNCTION: AcpiRsConvertResourceToAml
340 * PARAMETERS: Resource - Pointer to the resource descriptor
341 * Aml - Where the AML descriptor is returned
342 * Info - Pointer to appropriate conversion table
346 * DESCRIPTION: Convert an internal resource descriptor to the corresponding
347 * external AML resource descriptor.
349 ******************************************************************************/
352 AcpiRsConvertResourceToAml (
353 ACPI_RESOURCE *Resource,
355 ACPI_RSCONVERT_INFO *Info)
359 ACPI_RSDESC_SIZE AmlLength = 0;
362 UINT16 ItemCount = 0;
365 ACPI_FUNCTION_TRACE (RsConvertResourceToAml);
369 * First table entry must be ACPI_RSC_INITxxx and must contain the
370 * table length (# of table entries)
372 Count = INIT_TABLE_LENGTH (Info);
377 * Source is the internal resource descriptor,
378 * destination is the external AML byte stream buffer
380 Source = ACPI_ADD_PTR (void, Resource, Info->ResourceOffset);
381 Destination = ACPI_ADD_PTR (void, Aml, Info->AmlOffset);
383 switch (Info->Opcode)
385 case ACPI_RSC_INITSET:
387 ACPI_MEMSET (Aml, 0, INIT_RESOURCE_LENGTH (Info));
388 AmlLength = INIT_RESOURCE_LENGTH (Info);
389 AcpiRsSetResourceHeader (INIT_RESOURCE_TYPE (Info), AmlLength, Aml);
393 case ACPI_RSC_INITGET:
397 case ACPI_RSC_FLAGINIT:
399 * Clear the flag byte
401 ACPI_SET8 (Destination) = 0;
405 case ACPI_RSC_1BITFLAG:
407 * Mask and shift the flag bit
409 ACPI_SET8 (Destination) |= (UINT8)
410 ((ACPI_GET8 (Source) & 0x01) << Info->Value);
414 case ACPI_RSC_2BITFLAG:
416 * Mask and shift the flag bits
418 ACPI_SET8 (Destination) |= (UINT8)
419 ((ACPI_GET8 (Source) & 0x03) << Info->Value);
425 ItemCount = ACPI_GET8 (Source);
426 ACPI_SET8 (Destination) = (UINT8) ItemCount;
428 AmlLength = (UINT16) (AmlLength + (Info->Value * (ItemCount - 1)));
432 case ACPI_RSC_COUNT16:
434 ItemCount = ACPI_GET16 (Source);
435 AmlLength = (UINT16) (AmlLength + ItemCount);
436 AcpiRsSetResourceLength (AmlLength, Aml);
440 case ACPI_RSC_LENGTH:
442 AcpiRsSetResourceLength (Info->Value, Aml);
447 case ACPI_RSC_MOVE16:
448 case ACPI_RSC_MOVE32:
449 case ACPI_RSC_MOVE64:
453 ItemCount = Info->Value;
455 AcpiRsMoveData (Destination, Source, ItemCount, Info->Opcode);
459 case ACPI_RSC_ADDRESS:
461 /* Set the Resource Type, General Flags, and Type-Specific Flags */
463 AcpiRsSetAddressCommon (Aml, Resource);
467 case ACPI_RSC_SOURCEX:
469 * Optional ResourceSource (Index and String)
471 AmlLength = AcpiRsSetResourceSource (
472 Aml, (ACPI_RS_LENGTH) AmlLength, Source);
473 AcpiRsSetResourceLength (AmlLength, Aml);
477 case ACPI_RSC_SOURCE:
479 * Optional ResourceSource (Index and String). This is the more
480 * complicated case used by the Interrupt() macro
482 AmlLength = AcpiRsSetResourceSource (Aml, Info->Value, Source);
483 AcpiRsSetResourceLength (AmlLength, Aml);
487 case ACPI_RSC_BITMASK:
489 * 8-bit encoded bitmask (DMA macro)
491 ACPI_SET8 (Destination) = (UINT8)
492 AcpiRsEncodeBitmask (Source,
493 *ACPI_ADD_PTR (UINT8, Resource, Info->Value));
497 case ACPI_RSC_BITMASK16:
499 * 16-bit encoded bitmask (IRQ macro)
501 Temp16 = AcpiRsEncodeBitmask (Source,
502 *ACPI_ADD_PTR (UINT8, Resource, Info->Value));
503 ACPI_MOVE_16_TO_16 (Destination, &Temp16);
507 case ACPI_RSC_EXIT_LE:
509 * Control - Exit conversion if less than or equal
511 if (ItemCount <= Info->Value)
518 case ACPI_RSC_EXIT_NE:
520 * Control - Exit conversion if not equal
522 switch (COMPARE_OPCODE (Info))
524 case ACPI_RSC_COMPARE_VALUE:
526 if (*ACPI_ADD_PTR (UINT8, Resource,
527 COMPARE_TARGET (Info)) != COMPARE_VALUE (Info))
535 ACPI_ERROR ((AE_INFO, "Invalid conversion sub-opcode"));
536 return_ACPI_STATUS (AE_BAD_PARAMETER);
541 case ACPI_RSC_EXIT_EQ:
543 * Control - Exit conversion if equal
545 if (*ACPI_ADD_PTR (UINT8, Resource,
546 COMPARE_TARGET (Info)) == COMPARE_VALUE (Info))
555 ACPI_ERROR ((AE_INFO, "Invalid conversion opcode"));
556 return_ACPI_STATUS (AE_BAD_PARAMETER);
564 return_ACPI_STATUS (AE_OK);
569 /* Previous resource validations */
571 if (Aml->ExtAddress64.RevisionID != AML_RESOURCE_EXTENDED_ADDRESS_REVISION)
573 return_ACPI_STATUS (AE_SUPPORT);
576 if (Resource->Data.StartDpf.PerformanceRobustness >= 3)
578 return_ACPI_STATUS (AE_AML_BAD_RESOURCE_VALUE);
581 if (((Aml->Irq.Flags & 0x09) == 0x00) ||
582 ((Aml->Irq.Flags & 0x09) == 0x09))
585 * Only [ActiveHigh, EdgeSensitive] or [ActiveLow, LevelSensitive]
586 * polarity/trigger interrupts are allowed (ACPI spec, section
587 * "IRQ Format"), so 0x00 and 0x09 are illegal.
589 ACPI_ERROR ((AE_INFO,
590 "Invalid interrupt polarity/trigger in resource list, 0x%X",
592 return_ACPI_STATUS (AE_BAD_DATA);
595 Resource->Data.ExtendedIrq.InterruptCount = Temp8;
598 /* Must have at least one IRQ */
600 return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH);
603 if (Resource->Data.Dma.Transfer == 0x03)
605 ACPI_ERROR ((AE_INFO,
606 "Invalid DMA.Transfer preference (3)"));
607 return_ACPI_STATUS (AE_BAD_DATA);