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