1 | /******************************************************************************* |
2 | * |
3 | * Module Name: rsmisc - Miscellaneous resource descriptors |
4 | * |
5 | ******************************************************************************/ |
6 | |
7 | /* |
8 | * Copyright (C) 2000 - 2016, Intel Corp. |
9 | * All rights reserved. |
10 | * |
11 | * Redistribution and use in source and binary forms, with or without |
12 | * modification, are permitted provided that the following conditions |
13 | * are met: |
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. |
25 | * |
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. |
29 | * |
30 | * NO WARRANTY |
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. |
42 | */ |
43 | |
44 | #include "acpi.h" |
45 | #include "accommon.h" |
46 | #include "acresrc.h" |
47 | |
48 | #define _COMPONENT ACPI_RESOURCES |
49 | ACPI_MODULE_NAME ("rsmisc" ) |
50 | |
51 | |
52 | #define INIT_RESOURCE_TYPE(i) i->ResourceOffset |
53 | #define INIT_RESOURCE_LENGTH(i) i->AmlOffset |
54 | #define INIT_TABLE_LENGTH(i) i->Value |
55 | |
56 | #define COMPARE_OPCODE(i) i->ResourceOffset |
57 | #define COMPARE_TARGET(i) i->AmlOffset |
58 | #define COMPARE_VALUE(i) i->Value |
59 | |
60 | |
61 | /******************************************************************************* |
62 | * |
63 | * FUNCTION: AcpiRsConvertAmlToResource |
64 | * |
65 | * PARAMETERS: Resource - Pointer to the resource descriptor |
66 | * Aml - Where the AML descriptor is returned |
67 | * Info - Pointer to appropriate conversion table |
68 | * |
69 | * RETURN: Status |
70 | * |
71 | * DESCRIPTION: Convert an external AML resource descriptor to the corresponding |
72 | * internal resource descriptor |
73 | * |
74 | ******************************************************************************/ |
75 | |
76 | ACPI_STATUS |
77 | AcpiRsConvertAmlToResource ( |
78 | ACPI_RESOURCE *Resource, |
79 | AML_RESOURCE *Aml, |
80 | ACPI_RSCONVERT_INFO *Info) |
81 | { |
82 | ACPI_RS_LENGTH AmlResourceLength; |
83 | void *Source; |
84 | void *Destination; |
85 | char *Target; |
86 | UINT8 Count; |
87 | UINT8 FlagsMode = FALSE; |
88 | UINT16 ItemCount = 0; |
89 | UINT16 Temp16 = 0; |
90 | |
91 | |
92 | ACPI_FUNCTION_TRACE (RsConvertAmlToResource); |
93 | |
94 | |
95 | if (!Info) |
96 | { |
97 | return_ACPI_STATUS (AE_BAD_PARAMETER); |
98 | } |
99 | |
100 | if (((ACPI_SIZE) Resource) & 0x3) |
101 | { |
102 | /* Each internal resource struct is expected to be 32-bit aligned */ |
103 | |
104 | ACPI_WARNING ((AE_INFO, |
105 | "Misaligned resource pointer (get): %p Type 0x%2.2X Length %u" , |
106 | Resource, Resource->Type, Resource->Length)); |
107 | } |
108 | |
109 | /* Extract the resource Length field (does not include header length) */ |
110 | |
111 | AmlResourceLength = AcpiUtGetResourceLength (Aml); |
112 | |
113 | /* |
114 | * First table entry must be ACPI_RSC_INITxxx and must contain the |
115 | * table length (# of table entries) |
116 | */ |
117 | Count = INIT_TABLE_LENGTH (Info); |
118 | while (Count) |
119 | { |
120 | /* |
121 | * Source is the external AML byte stream buffer, |
122 | * destination is the internal resource descriptor |
123 | */ |
124 | Source = ACPI_ADD_PTR (void, Aml, Info->AmlOffset); |
125 | Destination = ACPI_ADD_PTR (void, Resource, Info->ResourceOffset); |
126 | |
127 | switch (Info->Opcode) |
128 | { |
129 | case ACPI_RSC_INITGET: |
130 | /* |
131 | * Get the resource type and the initial (minimum) length |
132 | */ |
133 | memset (Resource, 0, INIT_RESOURCE_LENGTH (Info)); |
134 | Resource->Type = INIT_RESOURCE_TYPE (Info); |
135 | Resource->Length = INIT_RESOURCE_LENGTH (Info); |
136 | break; |
137 | |
138 | case ACPI_RSC_INITSET: |
139 | break; |
140 | |
141 | case ACPI_RSC_FLAGINIT: |
142 | |
143 | FlagsMode = TRUE; |
144 | break; |
145 | |
146 | case ACPI_RSC_1BITFLAG: |
147 | /* |
148 | * Mask and shift the flag bit |
149 | */ |
150 | ACPI_SET8 (Destination, |
151 | ((ACPI_GET8 (Source) >> Info->Value) & 0x01)); |
152 | break; |
153 | |
154 | case ACPI_RSC_2BITFLAG: |
155 | /* |
156 | * Mask and shift the flag bits |
157 | */ |
158 | ACPI_SET8 (Destination, |
159 | ((ACPI_GET8 (Source) >> Info->Value) & 0x03)); |
160 | break; |
161 | |
162 | case ACPI_RSC_3BITFLAG: |
163 | /* |
164 | * Mask and shift the flag bits |
165 | */ |
166 | ACPI_SET8 (Destination, |
167 | ((ACPI_GET8 (Source) >> Info->Value) & 0x07)); |
168 | break; |
169 | |
170 | case ACPI_RSC_COUNT: |
171 | |
172 | ItemCount = ACPI_GET8 (Source); |
173 | ACPI_SET8 (Destination, ItemCount); |
174 | |
175 | Resource->Length = Resource->Length + |
176 | (Info->Value * (ItemCount - 1)); |
177 | break; |
178 | |
179 | case ACPI_RSC_COUNT16: |
180 | |
181 | ItemCount = AmlResourceLength; |
182 | ACPI_SET16 (Destination, ItemCount); |
183 | |
184 | Resource->Length = Resource->Length + |
185 | (Info->Value * (ItemCount - 1)); |
186 | break; |
187 | |
188 | case ACPI_RSC_COUNT_GPIO_PIN: |
189 | |
190 | Target = ACPI_ADD_PTR (void, Aml, Info->Value); |
191 | ItemCount = ACPI_GET16 (Target) - ACPI_GET16 (Source); |
192 | |
193 | Resource->Length = Resource->Length + ItemCount; |
194 | ItemCount = ItemCount / 2; |
195 | ACPI_SET16 (Destination, ItemCount); |
196 | break; |
197 | |
198 | case ACPI_RSC_COUNT_GPIO_VEN: |
199 | |
200 | ItemCount = ACPI_GET8 (Source); |
201 | ACPI_SET8 (Destination, ItemCount); |
202 | |
203 | Resource->Length = Resource->Length + (Info->Value * ItemCount); |
204 | break; |
205 | |
206 | case ACPI_RSC_COUNT_GPIO_RES: |
207 | /* |
208 | * Vendor data is optional (length/offset may both be zero) |
209 | * Examine vendor data length field first |
210 | */ |
211 | Target = ACPI_ADD_PTR (void, Aml, (Info->Value + 2)); |
212 | if (ACPI_GET16 (Target)) |
213 | { |
214 | /* Use vendor offset to get resource source length */ |
215 | |
216 | Target = ACPI_ADD_PTR (void, Aml, Info->Value); |
217 | ItemCount = ACPI_GET16 (Target) - ACPI_GET16 (Source); |
218 | } |
219 | else |
220 | { |
221 | /* No vendor data to worry about */ |
222 | |
223 | ItemCount = Aml->LargeHeader.ResourceLength + |
224 | sizeof (AML_RESOURCE_LARGE_HEADER) - |
225 | ACPI_GET16 (Source); |
226 | } |
227 | |
228 | Resource->Length = Resource->Length + ItemCount; |
229 | ACPI_SET16 (Destination, ItemCount); |
230 | break; |
231 | |
232 | case ACPI_RSC_COUNT_SERIAL_VEN: |
233 | |
234 | ItemCount = ACPI_GET16 (Source) - Info->Value; |
235 | |
236 | Resource->Length = Resource->Length + ItemCount; |
237 | ACPI_SET16 (Destination, ItemCount); |
238 | break; |
239 | |
240 | case ACPI_RSC_COUNT_SERIAL_RES: |
241 | |
242 | ItemCount = (AmlResourceLength + |
243 | sizeof (AML_RESOURCE_LARGE_HEADER)) - |
244 | ACPI_GET16 (Source) - Info->Value; |
245 | |
246 | Resource->Length = Resource->Length + ItemCount; |
247 | ACPI_SET16 (Destination, ItemCount); |
248 | break; |
249 | |
250 | case ACPI_RSC_LENGTH: |
251 | |
252 | Resource->Length = Resource->Length + Info->Value; |
253 | break; |
254 | |
255 | case ACPI_RSC_MOVE8: |
256 | case ACPI_RSC_MOVE16: |
257 | case ACPI_RSC_MOVE32: |
258 | case ACPI_RSC_MOVE64: |
259 | /* |
260 | * Raw data move. Use the Info value field unless ItemCount has |
261 | * been previously initialized via a COUNT opcode |
262 | */ |
263 | if (Info->Value) |
264 | { |
265 | ItemCount = Info->Value; |
266 | } |
267 | AcpiRsMoveData (Destination, Source, ItemCount, Info->Opcode); |
268 | break; |
269 | |
270 | case ACPI_RSC_MOVE_GPIO_PIN: |
271 | |
272 | /* Generate and set the PIN data pointer */ |
273 | |
274 | Target = (char *) ACPI_ADD_PTR (void, Resource, |
275 | (Resource->Length - ItemCount * 2)); |
276 | *(UINT16 **) Destination = ACPI_CAST_PTR (UINT16, Target); |
277 | |
278 | /* Copy the PIN data */ |
279 | |
280 | Source = ACPI_ADD_PTR (void, Aml, ACPI_GET16 (Source)); |
281 | AcpiRsMoveData (Target, Source, ItemCount, Info->Opcode); |
282 | break; |
283 | |
284 | case ACPI_RSC_MOVE_GPIO_RES: |
285 | |
286 | /* Generate and set the ResourceSource string pointer */ |
287 | |
288 | Target = (char *) ACPI_ADD_PTR (void, Resource, |
289 | (Resource->Length - ItemCount)); |
290 | *(UINT8 **) Destination = ACPI_CAST_PTR (UINT8, Target); |
291 | |
292 | /* Copy the ResourceSource string */ |
293 | |
294 | Source = ACPI_ADD_PTR (void, Aml, ACPI_GET16 (Source)); |
295 | AcpiRsMoveData (Target, Source, ItemCount, Info->Opcode); |
296 | break; |
297 | |
298 | case ACPI_RSC_MOVE_SERIAL_VEN: |
299 | |
300 | /* Generate and set the Vendor Data pointer */ |
301 | |
302 | Target = (char *) ACPI_ADD_PTR (void, Resource, |
303 | (Resource->Length - ItemCount)); |
304 | *(UINT8 **) Destination = ACPI_CAST_PTR (UINT8, Target); |
305 | |
306 | /* Copy the Vendor Data */ |
307 | |
308 | Source = ACPI_ADD_PTR (void, Aml, Info->Value); |
309 | AcpiRsMoveData (Target, Source, ItemCount, Info->Opcode); |
310 | break; |
311 | |
312 | case ACPI_RSC_MOVE_SERIAL_RES: |
313 | |
314 | /* Generate and set the ResourceSource string pointer */ |
315 | |
316 | Target = (char *) ACPI_ADD_PTR (void, Resource, |
317 | (Resource->Length - ItemCount)); |
318 | *(UINT8 **) Destination = ACPI_CAST_PTR (UINT8, Target); |
319 | |
320 | /* Copy the ResourceSource string */ |
321 | |
322 | Source = ACPI_ADD_PTR ( |
323 | void, Aml, (ACPI_GET16 (Source) + Info->Value)); |
324 | AcpiRsMoveData (Target, Source, ItemCount, Info->Opcode); |
325 | break; |
326 | |
327 | case ACPI_RSC_SET8: |
328 | |
329 | memset (Destination, Info->AmlOffset, Info->Value); |
330 | break; |
331 | |
332 | case ACPI_RSC_DATA8: |
333 | |
334 | Target = ACPI_ADD_PTR (char, Resource, Info->Value); |
335 | memcpy (Destination, Source, ACPI_GET16 (Target)); |
336 | break; |
337 | |
338 | case ACPI_RSC_ADDRESS: |
339 | /* |
340 | * Common handler for address descriptor flags |
341 | */ |
342 | if (!AcpiRsGetAddressCommon (Resource, Aml)) |
343 | { |
344 | return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE); |
345 | } |
346 | break; |
347 | |
348 | case ACPI_RSC_SOURCE: |
349 | /* |
350 | * Optional ResourceSource (Index and String) |
351 | */ |
352 | Resource->Length += |
353 | AcpiRsGetResourceSource (AmlResourceLength, Info->Value, |
354 | Destination, Aml, NULL); |
355 | break; |
356 | |
357 | case ACPI_RSC_SOURCEX: |
358 | /* |
359 | * Optional ResourceSource (Index and String). This is the more |
360 | * complicated case used by the Interrupt() macro |
361 | */ |
362 | Target = ACPI_ADD_PTR (char, Resource, |
363 | Info->AmlOffset + (ItemCount * 4)); |
364 | |
365 | Resource->Length += |
366 | AcpiRsGetResourceSource (AmlResourceLength, (ACPI_RS_LENGTH) |
367 | (((ItemCount - 1) * sizeof (UINT32)) + Info->Value), |
368 | Destination, Aml, Target); |
369 | break; |
370 | |
371 | case ACPI_RSC_BITMASK: |
372 | /* |
373 | * 8-bit encoded bitmask (DMA macro) |
374 | */ |
375 | ItemCount = AcpiRsDecodeBitmask (ACPI_GET8 (Source), Destination); |
376 | if (ItemCount) |
377 | { |
378 | Resource->Length += (ItemCount - 1); |
379 | } |
380 | |
381 | Target = ACPI_ADD_PTR (char, Resource, Info->Value); |
382 | ACPI_SET8 (Target, ItemCount); |
383 | break; |
384 | |
385 | case ACPI_RSC_BITMASK16: |
386 | /* |
387 | * 16-bit encoded bitmask (IRQ macro) |
388 | */ |
389 | ACPI_MOVE_16_TO_16 (&Temp16, Source); |
390 | |
391 | ItemCount = AcpiRsDecodeBitmask (Temp16, Destination); |
392 | if (ItemCount) |
393 | { |
394 | Resource->Length += (ItemCount - 1); |
395 | } |
396 | |
397 | Target = ACPI_ADD_PTR (char, Resource, Info->Value); |
398 | ACPI_SET8 (Target, ItemCount); |
399 | break; |
400 | |
401 | case ACPI_RSC_EXIT_NE: |
402 | /* |
403 | * Control - Exit conversion if not equal |
404 | */ |
405 | switch (Info->ResourceOffset) |
406 | { |
407 | case ACPI_RSC_COMPARE_AML_LENGTH: |
408 | |
409 | if (AmlResourceLength != Info->Value) |
410 | { |
411 | goto Exit; |
412 | } |
413 | break; |
414 | |
415 | case ACPI_RSC_COMPARE_VALUE: |
416 | |
417 | if (ACPI_GET8 (Source) != Info->Value) |
418 | { |
419 | goto Exit; |
420 | } |
421 | break; |
422 | |
423 | default: |
424 | |
425 | ACPI_ERROR ((AE_INFO, "Invalid conversion sub-opcode" )); |
426 | return_ACPI_STATUS (AE_BAD_PARAMETER); |
427 | } |
428 | break; |
429 | |
430 | default: |
431 | |
432 | ACPI_ERROR ((AE_INFO, "Invalid conversion opcode" )); |
433 | return_ACPI_STATUS (AE_BAD_PARAMETER); |
434 | } |
435 | |
436 | Count--; |
437 | Info++; |
438 | } |
439 | |
440 | Exit: |
441 | if (!FlagsMode) |
442 | { |
443 | /* Round the resource struct length up to the next boundary (32 or 64) */ |
444 | |
445 | Resource->Length = (UINT32) |
446 | ACPI_ROUND_UP_TO_NATIVE_WORD (Resource->Length); |
447 | } |
448 | return_ACPI_STATUS (AE_OK); |
449 | } |
450 | |
451 | |
452 | /******************************************************************************* |
453 | * |
454 | * FUNCTION: AcpiRsConvertResourceToAml |
455 | * |
456 | * PARAMETERS: Resource - Pointer to the resource descriptor |
457 | * Aml - Where the AML descriptor is returned |
458 | * Info - Pointer to appropriate conversion table |
459 | * |
460 | * RETURN: Status |
461 | * |
462 | * DESCRIPTION: Convert an internal resource descriptor to the corresponding |
463 | * external AML resource descriptor. |
464 | * |
465 | ******************************************************************************/ |
466 | |
467 | ACPI_STATUS |
468 | AcpiRsConvertResourceToAml ( |
469 | ACPI_RESOURCE *Resource, |
470 | AML_RESOURCE *Aml, |
471 | ACPI_RSCONVERT_INFO *Info) |
472 | { |
473 | void *Source = NULL; |
474 | void *Destination; |
475 | char *Target; |
476 | ACPI_RSDESC_SIZE AmlLength = 0; |
477 | UINT8 Count; |
478 | UINT16 Temp16 = 0; |
479 | UINT16 ItemCount = 0; |
480 | |
481 | |
482 | ACPI_FUNCTION_TRACE (RsConvertResourceToAml); |
483 | |
484 | |
485 | if (!Info) |
486 | { |
487 | return_ACPI_STATUS (AE_BAD_PARAMETER); |
488 | } |
489 | |
490 | /* |
491 | * First table entry must be ACPI_RSC_INITxxx and must contain the |
492 | * table length (# of table entries) |
493 | */ |
494 | Count = INIT_TABLE_LENGTH (Info); |
495 | |
496 | while (Count) |
497 | { |
498 | /* |
499 | * Source is the internal resource descriptor, |
500 | * destination is the external AML byte stream buffer |
501 | */ |
502 | Source = ACPI_ADD_PTR (void, Resource, Info->ResourceOffset); |
503 | Destination = ACPI_ADD_PTR (void, Aml, Info->AmlOffset); |
504 | |
505 | switch (Info->Opcode) |
506 | { |
507 | case ACPI_RSC_INITSET: |
508 | |
509 | memset (Aml, 0, INIT_RESOURCE_LENGTH (Info)); |
510 | AmlLength = INIT_RESOURCE_LENGTH (Info); |
511 | AcpiRsSetResourceHeader ( |
512 | INIT_RESOURCE_TYPE (Info), AmlLength, Aml); |
513 | break; |
514 | |
515 | case ACPI_RSC_INITGET: |
516 | break; |
517 | |
518 | case ACPI_RSC_FLAGINIT: |
519 | /* |
520 | * Clear the flag byte |
521 | */ |
522 | ACPI_SET8 (Destination, 0); |
523 | break; |
524 | |
525 | case ACPI_RSC_1BITFLAG: |
526 | /* |
527 | * Mask and shift the flag bit |
528 | */ |
529 | ACPI_SET_BIT (*ACPI_CAST8 (Destination), (UINT8) |
530 | ((ACPI_GET8 (Source) & 0x01) << Info->Value)); |
531 | break; |
532 | |
533 | case ACPI_RSC_2BITFLAG: |
534 | /* |
535 | * Mask and shift the flag bits |
536 | */ |
537 | ACPI_SET_BIT (*ACPI_CAST8 (Destination), (UINT8) |
538 | ((ACPI_GET8 (Source) & 0x03) << Info->Value)); |
539 | break; |
540 | |
541 | case ACPI_RSC_3BITFLAG: |
542 | /* |
543 | * Mask and shift the flag bits |
544 | */ |
545 | ACPI_SET_BIT (*ACPI_CAST8 (Destination), (UINT8) |
546 | ((ACPI_GET8 (Source) & 0x07) << Info->Value)); |
547 | break; |
548 | |
549 | case ACPI_RSC_COUNT: |
550 | |
551 | ItemCount = ACPI_GET8 (Source); |
552 | ACPI_SET8 (Destination, ItemCount); |
553 | |
554 | AmlLength = (UINT16) |
555 | (AmlLength + (Info->Value * (ItemCount - 1))); |
556 | break; |
557 | |
558 | case ACPI_RSC_COUNT16: |
559 | |
560 | ItemCount = ACPI_GET16 (Source); |
561 | AmlLength = (UINT16) (AmlLength + ItemCount); |
562 | AcpiRsSetResourceLength (AmlLength, Aml); |
563 | break; |
564 | |
565 | case ACPI_RSC_COUNT_GPIO_PIN: |
566 | |
567 | ItemCount = ACPI_GET16 (Source); |
568 | ACPI_SET16 (Destination, AmlLength); |
569 | |
570 | AmlLength = (UINT16) (AmlLength + ItemCount * 2); |
571 | Target = ACPI_ADD_PTR (void, Aml, Info->Value); |
572 | ACPI_SET16 (Target, AmlLength); |
573 | AcpiRsSetResourceLength (AmlLength, Aml); |
574 | break; |
575 | |
576 | case ACPI_RSC_COUNT_GPIO_VEN: |
577 | |
578 | ItemCount = ACPI_GET16 (Source); |
579 | ACPI_SET16 (Destination, ItemCount); |
580 | |
581 | AmlLength = (UINT16) ( |
582 | AmlLength + (Info->Value * ItemCount)); |
583 | AcpiRsSetResourceLength (AmlLength, Aml); |
584 | break; |
585 | |
586 | case ACPI_RSC_COUNT_GPIO_RES: |
587 | |
588 | /* Set resource source string length */ |
589 | |
590 | ItemCount = ACPI_GET16 (Source); |
591 | ACPI_SET16 (Destination, AmlLength); |
592 | |
593 | /* Compute offset for the Vendor Data */ |
594 | |
595 | AmlLength = (UINT16) (AmlLength + ItemCount); |
596 | Target = ACPI_ADD_PTR (void, Aml, Info->Value); |
597 | |
598 | /* Set vendor offset only if there is vendor data */ |
599 | |
600 | if (Resource->Data.Gpio.VendorLength) |
601 | { |
602 | ACPI_SET16 (Target, AmlLength); |
603 | } |
604 | |
605 | AcpiRsSetResourceLength (AmlLength, Aml); |
606 | break; |
607 | |
608 | case ACPI_RSC_COUNT_SERIAL_VEN: |
609 | |
610 | ItemCount = ACPI_GET16 (Source); |
611 | ACPI_SET16 (Destination, ItemCount + Info->Value); |
612 | AmlLength = (UINT16) (AmlLength + ItemCount); |
613 | AcpiRsSetResourceLength (AmlLength, Aml); |
614 | break; |
615 | |
616 | case ACPI_RSC_COUNT_SERIAL_RES: |
617 | |
618 | ItemCount = ACPI_GET16 (Source); |
619 | AmlLength = (UINT16) (AmlLength + ItemCount); |
620 | AcpiRsSetResourceLength (AmlLength, Aml); |
621 | break; |
622 | |
623 | case ACPI_RSC_LENGTH: |
624 | |
625 | AcpiRsSetResourceLength (Info->Value, Aml); |
626 | break; |
627 | |
628 | case ACPI_RSC_MOVE8: |
629 | case ACPI_RSC_MOVE16: |
630 | case ACPI_RSC_MOVE32: |
631 | case ACPI_RSC_MOVE64: |
632 | |
633 | if (Info->Value) |
634 | { |
635 | ItemCount = Info->Value; |
636 | } |
637 | AcpiRsMoveData (Destination, Source, ItemCount, Info->Opcode); |
638 | break; |
639 | |
640 | case ACPI_RSC_MOVE_GPIO_PIN: |
641 | |
642 | Destination = (char *) ACPI_ADD_PTR (void, Aml, |
643 | ACPI_GET16 (Destination)); |
644 | Source = * (UINT16 **) Source; |
645 | AcpiRsMoveData (Destination, Source, ItemCount, Info->Opcode); |
646 | break; |
647 | |
648 | case ACPI_RSC_MOVE_GPIO_RES: |
649 | |
650 | /* Used for both ResourceSource string and VendorData */ |
651 | |
652 | Destination = (char *) ACPI_ADD_PTR (void, Aml, |
653 | ACPI_GET16 (Destination)); |
654 | Source = * (UINT8 **) Source; |
655 | AcpiRsMoveData (Destination, Source, ItemCount, Info->Opcode); |
656 | break; |
657 | |
658 | case ACPI_RSC_MOVE_SERIAL_VEN: |
659 | |
660 | Destination = (char *) ACPI_ADD_PTR (void, Aml, |
661 | (AmlLength - ItemCount)); |
662 | Source = * (UINT8 **) Source; |
663 | AcpiRsMoveData (Destination, Source, ItemCount, Info->Opcode); |
664 | break; |
665 | |
666 | case ACPI_RSC_MOVE_SERIAL_RES: |
667 | |
668 | Destination = (char *) ACPI_ADD_PTR (void, Aml, |
669 | (AmlLength - ItemCount)); |
670 | Source = * (UINT8 **) Source; |
671 | AcpiRsMoveData (Destination, Source, ItemCount, Info->Opcode); |
672 | break; |
673 | |
674 | case ACPI_RSC_ADDRESS: |
675 | |
676 | /* Set the Resource Type, General Flags, and Type-Specific Flags */ |
677 | |
678 | AcpiRsSetAddressCommon (Aml, Resource); |
679 | break; |
680 | |
681 | case ACPI_RSC_SOURCEX: |
682 | /* |
683 | * Optional ResourceSource (Index and String) |
684 | */ |
685 | AmlLength = AcpiRsSetResourceSource ( |
686 | Aml, (ACPI_RS_LENGTH) AmlLength, Source); |
687 | AcpiRsSetResourceLength (AmlLength, Aml); |
688 | break; |
689 | |
690 | case ACPI_RSC_SOURCE: |
691 | /* |
692 | * Optional ResourceSource (Index and String). This is the more |
693 | * complicated case used by the Interrupt() macro |
694 | */ |
695 | AmlLength = AcpiRsSetResourceSource (Aml, Info->Value, Source); |
696 | AcpiRsSetResourceLength (AmlLength, Aml); |
697 | break; |
698 | |
699 | case ACPI_RSC_BITMASK: |
700 | /* |
701 | * 8-bit encoded bitmask (DMA macro) |
702 | */ |
703 | ACPI_SET8 (Destination, |
704 | AcpiRsEncodeBitmask (Source, |
705 | *ACPI_ADD_PTR (UINT8, Resource, Info->Value))); |
706 | break; |
707 | |
708 | case ACPI_RSC_BITMASK16: |
709 | /* |
710 | * 16-bit encoded bitmask (IRQ macro) |
711 | */ |
712 | Temp16 = AcpiRsEncodeBitmask ( |
713 | Source, *ACPI_ADD_PTR (UINT8, Resource, Info->Value)); |
714 | ACPI_MOVE_16_TO_16 (Destination, &Temp16); |
715 | break; |
716 | |
717 | case ACPI_RSC_EXIT_LE: |
718 | /* |
719 | * Control - Exit conversion if less than or equal |
720 | */ |
721 | if (ItemCount <= Info->Value) |
722 | { |
723 | goto Exit; |
724 | } |
725 | break; |
726 | |
727 | case ACPI_RSC_EXIT_NE: |
728 | /* |
729 | * Control - Exit conversion if not equal |
730 | */ |
731 | switch (COMPARE_OPCODE (Info)) |
732 | { |
733 | case ACPI_RSC_COMPARE_VALUE: |
734 | |
735 | if (*ACPI_ADD_PTR (UINT8, Resource, |
736 | COMPARE_TARGET (Info)) != COMPARE_VALUE (Info)) |
737 | { |
738 | goto Exit; |
739 | } |
740 | break; |
741 | |
742 | default: |
743 | |
744 | ACPI_ERROR ((AE_INFO, "Invalid conversion sub-opcode" )); |
745 | return_ACPI_STATUS (AE_BAD_PARAMETER); |
746 | } |
747 | break; |
748 | |
749 | case ACPI_RSC_EXIT_EQ: |
750 | /* |
751 | * Control - Exit conversion if equal |
752 | */ |
753 | if (*ACPI_ADD_PTR (UINT8, Resource, |
754 | COMPARE_TARGET (Info)) == COMPARE_VALUE (Info)) |
755 | { |
756 | goto Exit; |
757 | } |
758 | break; |
759 | |
760 | default: |
761 | |
762 | ACPI_ERROR ((AE_INFO, "Invalid conversion opcode" )); |
763 | return_ACPI_STATUS (AE_BAD_PARAMETER); |
764 | } |
765 | |
766 | Count--; |
767 | Info++; |
768 | } |
769 | |
770 | Exit: |
771 | return_ACPI_STATUS (AE_OK); |
772 | } |
773 | |
774 | |
775 | #if 0 |
776 | /* Previous resource validations */ |
777 | |
778 | if (Aml->ExtAddress64.RevisionID != |
779 | AML_RESOURCE_EXTENDED_ADDRESS_REVISION) |
780 | { |
781 | return_ACPI_STATUS (AE_SUPPORT); |
782 | } |
783 | |
784 | if (Resource->Data.StartDpf.PerformanceRobustness >= 3) |
785 | { |
786 | return_ACPI_STATUS (AE_AML_BAD_RESOURCE_VALUE); |
787 | } |
788 | |
789 | if (((Aml->Irq.Flags & 0x09) == 0x00) || |
790 | ((Aml->Irq.Flags & 0x09) == 0x09)) |
791 | { |
792 | /* |
793 | * Only [ActiveHigh, EdgeSensitive] or [ActiveLow, LevelSensitive] |
794 | * polarity/trigger interrupts are allowed (ACPI spec, section |
795 | * "IRQ Format"), so 0x00 and 0x09 are illegal. |
796 | */ |
797 | ACPI_ERROR ((AE_INFO, |
798 | "Invalid interrupt polarity/trigger in resource list, 0x%X" , |
799 | Aml->Irq.Flags)); |
800 | return_ACPI_STATUS (AE_BAD_DATA); |
801 | } |
802 | |
803 | Resource->Data.ExtendedIrq.InterruptCount = Temp8; |
804 | if (Temp8 < 1) |
805 | { |
806 | /* Must have at least one IRQ */ |
807 | |
808 | return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH); |
809 | } |
810 | |
811 | if (Resource->Data.Dma.Transfer == 0x03) |
812 | { |
813 | ACPI_ERROR ((AE_INFO, |
814 | "Invalid DMA.Transfer preference (3)" )); |
815 | return_ACPI_STATUS (AE_BAD_DATA); |
816 | } |
817 | #endif |
818 | |