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