dmbuffer.c revision 1.1.1.4 1 /*******************************************************************************
2 *
3 * Module Name: dmbuffer - AML disassembler, buffer and string support
4 *
5 ******************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2014, 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 "acutils.h"
47 #include "acdisasm.h"
48 #include "acparser.h"
49 #include "amlcode.h"
50 #include "acinterp.h"
51
52
53 #ifdef ACPI_DISASSEMBLER
54
55 #define _COMPONENT ACPI_CA_DEBUGGER
56 ACPI_MODULE_NAME ("dmbuffer")
57
58 /* Local prototypes */
59
60 static void
61 AcpiDmUuid (
62 ACPI_PARSE_OBJECT *Op);
63
64 static void
65 AcpiDmUnicode (
66 ACPI_PARSE_OBJECT *Op);
67
68 static void
69 AcpiDmGetHardwareIdType (
70 ACPI_PARSE_OBJECT *Op);
71
72 static void
73 AcpiDmPldBuffer (
74 UINT32 Level,
75 UINT8 *ByteData,
76 UINT32 ByteCount);
77
78
79 #define ACPI_BUFFER_BYTES_PER_LINE 8
80
81
82 /*******************************************************************************
83 *
84 * FUNCTION: AcpiDmDisasmByteList
85 *
86 * PARAMETERS: Level - Current source code indentation level
87 * ByteData - Pointer to the byte list
88 * ByteCount - Length of the byte list
89 *
90 * RETURN: None
91 *
92 * DESCRIPTION: Dump an AML "ByteList" in Hex format. 8 bytes per line, prefixed
93 * with the hex buffer offset.
94 *
95 ******************************************************************************/
96
97 void
98 AcpiDmDisasmByteList (
99 UINT32 Level,
100 UINT8 *ByteData,
101 UINT32 ByteCount)
102 {
103 UINT32 i;
104 UINT32 j;
105 UINT32 CurrentIndex;
106 UINT8 BufChar;
107
108
109 if (!ByteCount)
110 {
111 return;
112 }
113
114 for (i = 0; i < ByteCount; i += ACPI_BUFFER_BYTES_PER_LINE)
115 {
116 /* Line indent and offset prefix for each new line */
117
118 AcpiDmIndent (Level);
119 if (ByteCount > ACPI_BUFFER_BYTES_PER_LINE)
120 {
121 AcpiOsPrintf ("/* %04X */ ", i);
122 }
123
124 /* Dump the actual hex values */
125
126 for (j = 0; j < ACPI_BUFFER_BYTES_PER_LINE; j++)
127 {
128 CurrentIndex = i + j;
129 if (CurrentIndex >= ByteCount)
130 {
131 /* Dump fill spaces */
132
133 AcpiOsPrintf (" ");
134 continue;
135 }
136
137 AcpiOsPrintf (" 0x%2.2X", ByteData[CurrentIndex]);
138
139 /* Add comma if there are more bytes to display */
140
141 if (CurrentIndex < (ByteCount - 1))
142 {
143 AcpiOsPrintf (",");
144 }
145 else
146 {
147 AcpiOsPrintf (" ");
148 }
149 }
150
151 /* Dump the ASCII equivalents within a comment */
152
153 AcpiOsPrintf (" /* ");
154 for (j = 0; j < ACPI_BUFFER_BYTES_PER_LINE; j++)
155 {
156 CurrentIndex = i + j;
157 if (CurrentIndex >= ByteCount)
158 {
159 break;
160 }
161
162 BufChar = ByteData[CurrentIndex];
163 if (ACPI_IS_PRINT (BufChar))
164 {
165 AcpiOsPrintf ("%c", BufChar);
166 }
167 else
168 {
169 AcpiOsPrintf (".");
170 }
171 }
172
173 /* Finished with this line */
174
175 AcpiOsPrintf (" */\n");
176 }
177 }
178
179
180 /*******************************************************************************
181 *
182 * FUNCTION: AcpiDmByteList
183 *
184 * PARAMETERS: Info - Parse tree walk info
185 * Op - Byte list op
186 *
187 * RETURN: None
188 *
189 * DESCRIPTION: Dump a buffer byte list, handling the various types of buffers.
190 * Buffer type must be already set in the Op DisasmOpcode.
191 *
192 ******************************************************************************/
193
194 void
195 AcpiDmByteList (
196 ACPI_OP_WALK_INFO *Info,
197 ACPI_PARSE_OBJECT *Op)
198 {
199 UINT8 *ByteData;
200 UINT32 ByteCount;
201
202
203 ByteData = Op->Named.Data;
204 ByteCount = (UINT32) Op->Common.Value.Integer;
205
206 /*
207 * The byte list belongs to a buffer, and can be produced by either
208 * a ResourceTemplate, Unicode, quoted string, or a plain byte list.
209 */
210 switch (Op->Common.Parent->Common.DisasmOpcode)
211 {
212 case ACPI_DASM_RESOURCE:
213
214 AcpiDmResourceTemplate (Info, Op->Common.Parent, ByteData, ByteCount);
215 break;
216
217 case ACPI_DASM_STRING:
218
219 AcpiDmIndent (Info->Level);
220 AcpiUtPrintString ((char *) ByteData, ACPI_UINT16_MAX);
221 AcpiOsPrintf ("\n");
222 break;
223
224 case ACPI_DASM_UUID:
225
226 AcpiDmUuid (Op);
227 break;
228
229 case ACPI_DASM_UNICODE:
230
231 AcpiDmUnicode (Op);
232 break;
233
234 case ACPI_DASM_PLD_METHOD:
235
236 AcpiDmDisasmByteList (Info->Level, ByteData, ByteCount);
237 AcpiDmPldBuffer (Info->Level, ByteData, ByteCount);
238 break;
239
240 case ACPI_DASM_BUFFER:
241 default:
242 /*
243 * Not a resource, string, or unicode string.
244 * Just dump the buffer
245 */
246 AcpiDmDisasmByteList (Info->Level, ByteData, ByteCount);
247 break;
248 }
249 }
250
251
252 /*******************************************************************************
253 *
254 * FUNCTION: AcpiDmIsUuidBuffer
255 *
256 * PARAMETERS: Op - Buffer Object to be examined
257 *
258 * RETURN: TRUE if buffer contains a UUID
259 *
260 * DESCRIPTION: Determine if a buffer Op contains a UUID
261 *
262 * To help determine whether the buffer is a UUID versus a raw data buffer,
263 * there a are a couple bytes we can look at:
264 *
265 * xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
266 *
267 * The variant covered by the UUID specification is indicated by the two most
268 * significant bits of N being 1 0 (i.e., the hexadecimal N will always be
269 * 8, 9, A, or B).
270 *
271 * The variant covered by the UUID specification has five versions. For this
272 * variant, the four bits of M indicates the UUID version (i.e., the
273 * hexadecimal M will be either 1, 2, 3, 4, or 5).
274 *
275 ******************************************************************************/
276
277 BOOLEAN
278 AcpiDmIsUuidBuffer (
279 ACPI_PARSE_OBJECT *Op)
280 {
281 UINT8 *ByteData;
282 UINT32 ByteCount;
283 ACPI_PARSE_OBJECT *SizeOp;
284 ACPI_PARSE_OBJECT *NextOp;
285
286
287 /* Buffer size is the buffer argument */
288
289 SizeOp = Op->Common.Value.Arg;
290
291 /* Next, the initializer byte list to examine */
292
293 NextOp = SizeOp->Common.Next;
294 if (!NextOp)
295 {
296 return (FALSE);
297 }
298
299 /* Extract the byte list info */
300
301 ByteData = NextOp->Named.Data;
302 ByteCount = (UINT32) NextOp->Common.Value.Integer;
303
304 /* Byte count must be exactly 16 */
305
306 if (ByteCount != UUID_BUFFER_LENGTH)
307 {
308 return (FALSE);
309 }
310
311 /* Check for valid "M" and "N" values (see function header above) */
312
313 if (((ByteData[7] & 0xF0) == 0x00) || /* M={1,2,3,4,5} */
314 ((ByteData[7] & 0xF0) > 0x50) ||
315 ((ByteData[8] & 0xF0) < 0x80) || /* N={8,9,A,B} */
316 ((ByteData[8] & 0xF0) > 0xB0))
317 {
318 return (FALSE);
319 }
320
321 /* Ignore the Size argument in the disassembly of this buffer op */
322
323 SizeOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
324 return (TRUE);
325 }
326
327
328 /*******************************************************************************
329 *
330 * FUNCTION: AcpiDmUuid
331 *
332 * PARAMETERS: Op - Byte List op containing a UUID
333 *
334 * RETURN: None
335 *
336 * DESCRIPTION: Dump a buffer containing a UUID as a standard ASCII string.
337 *
338 * Output Format:
339 * In its canonical form, the UUID is represented by a string containing 32
340 * lowercase hexadecimal digits, displayed in 5 groups separated by hyphens.
341 * The complete form is 8-4-4-4-12 for a total of 36 characters (32
342 * alphanumeric characters representing hex digits and 4 hyphens). In bytes,
343 * 4-2-2-2-6. Example:
344 *
345 * ToUUID ("107ededd-d381-4fd7-8da9-08e9a6c79644")
346 *
347 ******************************************************************************/
348
349 static void
350 AcpiDmUuid (
351 ACPI_PARSE_OBJECT *Op)
352 {
353 UINT8 *Data;
354 const char *Description;
355
356
357 Data = ACPI_CAST_PTR (UINT8, Op->Named.Data);
358
359 /* Emit the 36-byte UUID string in the proper format/order */
360
361 AcpiOsPrintf (
362 "\"%2.2x%2.2x%2.2x%2.2x-"
363 "%2.2x%2.2x-"
364 "%2.2x%2.2x-"
365 "%2.2x%2.2x-"
366 "%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\")",
367 Data[3], Data[2], Data[1], Data[0],
368 Data[5], Data[4],
369 Data[7], Data[6],
370 Data[8], Data[9],
371 Data[10], Data[11], Data[12], Data[13], Data[14], Data[15]);
372
373 /* Dump the UUID description string if available */
374
375 Description = AcpiAhMatchUuid (Data);
376 if (Description)
377 {
378 AcpiOsPrintf (" /* %s */", Description);
379 }
380 }
381
382
383 /*******************************************************************************
384 *
385 * FUNCTION: AcpiDmIsUnicodeBuffer
386 *
387 * PARAMETERS: Op - Buffer Object to be examined
388 *
389 * RETURN: TRUE if buffer contains a UNICODE string
390 *
391 * DESCRIPTION: Determine if a buffer Op contains a Unicode string
392 *
393 ******************************************************************************/
394
395 BOOLEAN
396 AcpiDmIsUnicodeBuffer (
397 ACPI_PARSE_OBJECT *Op)
398 {
399 UINT8 *ByteData;
400 UINT32 ByteCount;
401 UINT32 WordCount;
402 ACPI_PARSE_OBJECT *SizeOp;
403 ACPI_PARSE_OBJECT *NextOp;
404 UINT32 i;
405
406
407 /* Buffer size is the buffer argument */
408
409 SizeOp = Op->Common.Value.Arg;
410
411 /* Next, the initializer byte list to examine */
412
413 NextOp = SizeOp->Common.Next;
414 if (!NextOp)
415 {
416 return (FALSE);
417 }
418
419 /* Extract the byte list info */
420
421 ByteData = NextOp->Named.Data;
422 ByteCount = (UINT32) NextOp->Common.Value.Integer;
423 WordCount = ACPI_DIV_2 (ByteCount);
424
425 /*
426 * Unicode string must have an even number of bytes and last
427 * word must be zero
428 */
429 if ((!ByteCount) ||
430 (ByteCount < 4) ||
431 (ByteCount & 1) ||
432 ((UINT16 *) (void *) ByteData)[WordCount - 1] != 0)
433 {
434 return (FALSE);
435 }
436
437 /* For each word, 1st byte must be ascii, 2nd byte must be zero */
438
439 for (i = 0; i < (ByteCount - 2); i += 2)
440 {
441 if ((!ACPI_IS_PRINT (ByteData[i])) ||
442 (ByteData[(ACPI_SIZE) i + 1] != 0))
443 {
444 return (FALSE);
445 }
446 }
447
448 /* Ignore the Size argument in the disassembly of this buffer op */
449
450 SizeOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
451 return (TRUE);
452 }
453
454
455 /*******************************************************************************
456 *
457 * FUNCTION: AcpiDmIsStringBuffer
458 *
459 * PARAMETERS: Op - Buffer Object to be examined
460 *
461 * RETURN: TRUE if buffer contains a ASCII string, FALSE otherwise
462 *
463 * DESCRIPTION: Determine if a buffer Op contains a ASCII string
464 *
465 ******************************************************************************/
466
467 BOOLEAN
468 AcpiDmIsStringBuffer (
469 ACPI_PARSE_OBJECT *Op)
470 {
471 UINT8 *ByteData;
472 UINT32 ByteCount;
473 ACPI_PARSE_OBJECT *SizeOp;
474 ACPI_PARSE_OBJECT *NextOp;
475 UINT32 i;
476
477
478 /* Buffer size is the buffer argument */
479
480 SizeOp = Op->Common.Value.Arg;
481
482 /* Next, the initializer byte list to examine */
483
484 NextOp = SizeOp->Common.Next;
485 if (!NextOp)
486 {
487 return (FALSE);
488 }
489
490 /* Extract the byte list info */
491
492 ByteData = NextOp->Named.Data;
493 ByteCount = (UINT32) NextOp->Common.Value.Integer;
494
495 /* Last byte must be the null terminator */
496
497 if ((!ByteCount) ||
498 (ByteCount < 2) ||
499 (ByteData[ByteCount-1] != 0))
500 {
501 return (FALSE);
502 }
503
504 for (i = 0; i < (ByteCount - 1); i++)
505 {
506 /* TBD: allow some escapes (non-ascii chars).
507 * they will be handled in the string output routine
508 */
509
510 if (!ACPI_IS_PRINT (ByteData[i]))
511 {
512 return (FALSE);
513 }
514 }
515
516 return (TRUE);
517 }
518
519
520 /*******************************************************************************
521 *
522 * FUNCTION: AcpiDmIsPldBuffer
523 *
524 * PARAMETERS: Op - Buffer Object to be examined
525 *
526 * RETURN: TRUE if buffer contains a ASCII string, FALSE otherwise
527 *
528 * DESCRIPTION: Determine if a buffer Op contains a _PLD structure
529 *
530 ******************************************************************************/
531
532 BOOLEAN
533 AcpiDmIsPldBuffer (
534 ACPI_PARSE_OBJECT *Op)
535 {
536 ACPI_NAMESPACE_NODE *Node;
537 ACPI_PARSE_OBJECT *ParentOp;
538
539
540 ParentOp = Op->Common.Parent;
541 if (!ParentOp)
542 {
543 return (FALSE);
544 }
545
546 /* Check for form: Name(_PLD, Buffer() {}). Not legal, however */
547
548 if (ParentOp->Common.AmlOpcode == AML_NAME_OP)
549 {
550 Node = ParentOp->Common.Node;
551
552 if (ACPI_COMPARE_NAME (Node->Name.Ascii, METHOD_NAME__PLD))
553 {
554 return (TRUE);
555 }
556
557 return (FALSE);
558 }
559
560 /* Check for proper form: Name(_PLD, Package() {Buffer() {}}) */
561
562 if (ParentOp->Common.AmlOpcode == AML_PACKAGE_OP)
563 {
564 ParentOp = ParentOp->Common.Parent;
565 if (!ParentOp)
566 {
567 return (FALSE);
568 }
569
570 if (ParentOp->Common.AmlOpcode == AML_NAME_OP)
571 {
572 Node = ParentOp->Common.Node;
573
574 if (ACPI_COMPARE_NAME (Node->Name.Ascii, METHOD_NAME__PLD))
575 {
576 return (TRUE);
577 }
578 }
579 }
580
581 return (FALSE);
582 }
583
584
585 /*******************************************************************************
586 *
587 * FUNCTION: AcpiDmPldBuffer
588 *
589 * PARAMETERS: Level - Current source code indentation level
590 * ByteData - Pointer to the byte list
591 * ByteCount - Length of the byte list
592 *
593 * RETURN: None
594 *
595 * DESCRIPTION: Dump and format the contents of a _PLD buffer object
596 *
597 ******************************************************************************/
598
599 #define ACPI_PLD_OUTPUT08 "%*.s/* %18s : %-6.2X */\n", ACPI_MUL_4 (Level), " "
600 #define ACPI_PLD_OUTPUT16 "%*.s/* %18s : %-6.4X */\n", ACPI_MUL_4 (Level), " "
601 #define ACPI_PLD_OUTPUT24 "%*.s/* %18s : %-6.6X */\n", ACPI_MUL_4 (Level), " "
602
603 static void
604 AcpiDmPldBuffer (
605 UINT32 Level,
606 UINT8 *ByteData,
607 UINT32 ByteCount)
608 {
609 ACPI_PLD_INFO *PldInfo;
610 ACPI_STATUS Status;
611
612
613 /* Check for valid byte count */
614
615 if (ByteCount < ACPI_PLD_REV1_BUFFER_SIZE)
616 {
617 return;
618 }
619
620 /* Convert _PLD buffer to local _PLD struct */
621
622 Status = AcpiDecodePldBuffer (ByteData, ByteCount, &PldInfo);
623 if (ACPI_FAILURE (Status))
624 {
625 return;
626 }
627
628 /* First 32-bit dword */
629
630 AcpiOsPrintf (ACPI_PLD_OUTPUT08, "Revision", PldInfo->Revision);
631 AcpiOsPrintf (ACPI_PLD_OUTPUT08, "IgnoreColor", PldInfo->IgnoreColor);
632 AcpiOsPrintf (ACPI_PLD_OUTPUT24,"Color", PldInfo->Color);
633
634 /* Second 32-bit dword */
635
636 AcpiOsPrintf (ACPI_PLD_OUTPUT16,"Width", PldInfo->Width);
637 AcpiOsPrintf (ACPI_PLD_OUTPUT16,"Height", PldInfo->Height);
638
639 /* Third 32-bit dword */
640
641 AcpiOsPrintf (ACPI_PLD_OUTPUT08, "UserVisible", PldInfo->UserVisible);
642 AcpiOsPrintf (ACPI_PLD_OUTPUT08, "Dock", PldInfo->Dock);
643 AcpiOsPrintf (ACPI_PLD_OUTPUT08, "Lid", PldInfo->Lid);
644 AcpiOsPrintf (ACPI_PLD_OUTPUT08, "Panel", PldInfo->Panel);
645 AcpiOsPrintf (ACPI_PLD_OUTPUT08, "VerticalPosition", PldInfo->VerticalPosition);
646 AcpiOsPrintf (ACPI_PLD_OUTPUT08, "HorizontalPosition", PldInfo->HorizontalPosition);
647 AcpiOsPrintf (ACPI_PLD_OUTPUT08, "Shape", PldInfo->Shape);
648 AcpiOsPrintf (ACPI_PLD_OUTPUT08, "GroupOrientation", PldInfo->GroupOrientation);
649 AcpiOsPrintf (ACPI_PLD_OUTPUT08, "GroupToken", PldInfo->GroupToken);
650 AcpiOsPrintf (ACPI_PLD_OUTPUT08, "GroupPosition", PldInfo->GroupPosition);
651 AcpiOsPrintf (ACPI_PLD_OUTPUT08, "Bay", PldInfo->Bay);
652
653 /* Fourth 32-bit dword */
654
655 AcpiOsPrintf (ACPI_PLD_OUTPUT08, "Ejectable", PldInfo->Ejectable);
656 AcpiOsPrintf (ACPI_PLD_OUTPUT08, "OspmEjectRequired", PldInfo->OspmEjectRequired);
657 AcpiOsPrintf (ACPI_PLD_OUTPUT08, "CabinetNumber", PldInfo->CabinetNumber);
658 AcpiOsPrintf (ACPI_PLD_OUTPUT08, "CardCageNumber", PldInfo->CardCageNumber);
659 AcpiOsPrintf (ACPI_PLD_OUTPUT08, "Reference", PldInfo->Reference);
660 AcpiOsPrintf (ACPI_PLD_OUTPUT08, "Rotation", PldInfo->Rotation);
661 AcpiOsPrintf (ACPI_PLD_OUTPUT08, "Order", PldInfo->Order);
662
663 /* Fifth 32-bit dword */
664
665 if (ByteCount >= ACPI_PLD_REV1_BUFFER_SIZE)
666 {
667 AcpiOsPrintf (ACPI_PLD_OUTPUT16,"VerticalOffset", PldInfo->VerticalOffset);
668 AcpiOsPrintf (ACPI_PLD_OUTPUT16,"HorizontalOffset", PldInfo->HorizontalOffset);
669 }
670
671 ACPI_FREE (PldInfo);
672 }
673
674
675 /*******************************************************************************
676 *
677 * FUNCTION: AcpiDmUnicode
678 *
679 * PARAMETERS: Op - Byte List op containing Unicode string
680 *
681 * RETURN: None
682 *
683 * DESCRIPTION: Dump Unicode string as a standard ASCII string. (Remove
684 * the extra zero bytes).
685 *
686 ******************************************************************************/
687
688 static void
689 AcpiDmUnicode (
690 ACPI_PARSE_OBJECT *Op)
691 {
692 UINT16 *WordData;
693 UINT32 WordCount;
694 UINT32 i;
695
696
697 /* Extract the buffer info as a WORD buffer */
698
699 WordData = ACPI_CAST_PTR (UINT16, Op->Named.Data);
700 WordCount = ACPI_DIV_2 (((UINT32) Op->Common.Value.Integer));
701
702 /* Write every other byte as an ASCII character */
703
704 AcpiOsPrintf ("\"");
705 for (i = 0; i < (WordCount - 1); i++)
706 {
707 AcpiOsPrintf ("%c", (int) WordData[i]);
708 }
709
710 AcpiOsPrintf ("\")");
711 }
712
713
714 /*******************************************************************************
715 *
716 * FUNCTION: AcpiDmGetHardwareIdType
717 *
718 * PARAMETERS: Op - Op to be examined
719 *
720 * RETURN: None
721 *
722 * DESCRIPTION: Determine the type of the argument to a _HID or _CID
723 * 1) Strings are allowed
724 * 2) If Integer, determine if it is a valid EISAID
725 *
726 ******************************************************************************/
727
728 static void
729 AcpiDmGetHardwareIdType (
730 ACPI_PARSE_OBJECT *Op)
731 {
732 UINT32 BigEndianId;
733 UINT32 Prefix[3];
734 UINT32 i;
735
736
737 switch (Op->Common.AmlOpcode)
738 {
739 case AML_STRING_OP:
740
741 /* Mark this string as an _HID/_CID string */
742
743 Op->Common.DisasmOpcode = ACPI_DASM_HID_STRING;
744 break;
745
746 case AML_WORD_OP:
747 case AML_DWORD_OP:
748
749 /* Determine if a Word/Dword is a valid encoded EISAID */
750
751 /* Swap from little-endian to big-endian to simplify conversion */
752
753 BigEndianId = AcpiUtDwordByteSwap ((UINT32) Op->Common.Value.Integer);
754
755 /* Create the 3 leading ASCII letters */
756
757 Prefix[0] = ((BigEndianId >> 26) & 0x1F) + 0x40;
758 Prefix[1] = ((BigEndianId >> 21) & 0x1F) + 0x40;
759 Prefix[2] = ((BigEndianId >> 16) & 0x1F) + 0x40;
760
761 /* Verify that all 3 are ascii and alpha */
762
763 for (i = 0; i < 3; i++)
764 {
765 if (!ACPI_IS_ASCII (Prefix[i]) ||
766 !ACPI_IS_ALPHA (Prefix[i]))
767 {
768 return;
769 }
770 }
771
772 /* Mark this node as convertable to an EISA ID string */
773
774 Op->Common.DisasmOpcode = ACPI_DASM_EISAID;
775 break;
776
777 default:
778 break;
779 }
780 }
781
782
783 /*******************************************************************************
784 *
785 * FUNCTION: AcpiDmCheckForHardwareId
786 *
787 * PARAMETERS: Op - Op to be examined
788 *
789 * RETURN: None
790 *
791 * DESCRIPTION: Determine if a Name() Op is a _HID/_CID.
792 *
793 ******************************************************************************/
794
795 void
796 AcpiDmCheckForHardwareId (
797 ACPI_PARSE_OBJECT *Op)
798 {
799 UINT32 Name;
800 ACPI_PARSE_OBJECT *NextOp;
801
802
803 /* Get the NameSegment */
804
805 Name = AcpiPsGetName (Op);
806 if (!Name)
807 {
808 return;
809 }
810
811 NextOp = AcpiPsGetDepthNext (NULL, Op);
812 if (!NextOp)
813 {
814 return;
815 }
816
817 /* Check for _HID - has one argument */
818
819 if (ACPI_COMPARE_NAME (&Name, METHOD_NAME__HID))
820 {
821 AcpiDmGetHardwareIdType (NextOp);
822 return;
823 }
824
825 /* Exit if not _CID */
826
827 if (!ACPI_COMPARE_NAME (&Name, METHOD_NAME__CID))
828 {
829 return;
830 }
831
832 /* _CID can contain a single argument or a package */
833
834 if (NextOp->Common.AmlOpcode != AML_PACKAGE_OP)
835 {
836 AcpiDmGetHardwareIdType (NextOp);
837 return;
838 }
839
840 /* _CID with Package: get the package length, check all elements */
841
842 NextOp = AcpiPsGetDepthNext (NULL, NextOp);
843 if (!NextOp)
844 {
845 return;
846 }
847
848 /* Don't need to use the length, just walk the peer list */
849
850 NextOp = NextOp->Common.Next;
851 while (NextOp)
852 {
853 AcpiDmGetHardwareIdType (NextOp);
854 NextOp = NextOp->Common.Next;
855 }
856 }
857
858
859 /*******************************************************************************
860 *
861 * FUNCTION: AcpiDmDecompressEisaId
862 *
863 * PARAMETERS: EncodedId - Raw encoded EISA ID.
864 *
865 * RETURN: None
866 *
867 * DESCRIPTION: Convert an encoded EISAID back to the original ASCII String
868 * and emit the correct ASL statement. If the ID is known, emit
869 * a description of the ID as a comment.
870 *
871 ******************************************************************************/
872
873 void
874 AcpiDmDecompressEisaId (
875 UINT32 EncodedId)
876 {
877 char IdBuffer[ACPI_EISAID_STRING_SIZE];
878 const AH_DEVICE_ID *Info;
879
880
881 /* Convert EISAID to a string an emit the statement */
882
883 AcpiExEisaIdToString (IdBuffer, EncodedId);
884 AcpiOsPrintf ("EisaId (\"%s\")", IdBuffer);
885
886 /* If we know about the ID, emit the description */
887
888 Info = AcpiAhMatchHardwareId (IdBuffer);
889 if (Info)
890 {
891 AcpiOsPrintf (" /* %s */", Info->Description);
892 }
893 }
894
895 #endif
896