ACPI.c revision d3a595ceb902372504db27442bca278c67d41b10
1/*++
2  This file contains an 'Intel UEFI Application' and is
3  licensed for Intel CPUs and chipsets under the terms of your
4  license agreement with Intel or your vendor.  This file may
5  be modified by the user, subject to additional terms of the
6  license agreement
7--*/
8/*++
9
10Copyright (c)  2011 Intel Corporation. All rights reserved
11This software and associated documentation (if any) is furnished
12under a license and may only be used or copied in accordance
13with the terms of the license. Except as permitted by such
14license, no part of this software or documentation may be
15reproduced, stored in a retrieval system, or transmitted in any
16form or by any means without the express written consent of
17Intel Corporation.
18
19--*/
20
21/** @file
22  Display the runtime services table
23
24**/
25
26#include <WebServer.h>
27#include <Guid/Acpi.h>
28#include <IndustryStandard/Acpi10.h>
29#include <IndustryStandard/Acpi30.h>
30
31#if defined(_MSC_VER)   //  Handle Microsoft VC++ compiler specifics.
32#pragma warning ( disable : 4305 )
33#endif  //  defined(_MSC_VER)
34
35//
36// Ensure proper structure formats
37//
38#pragma pack(1)
39
40typedef struct {
41  UINT8 AddressSpaceId;
42  UINT8 RegisterBitWidth;
43  UINT8 RegisterBitOffset;
44  UINT8 AccessSize;
45  UINT64 Address;
46} GENERIC_ADDRESS;
47
48
49typedef struct {
50  UINT32 Signature;           //    0
51  UINT32 Length;              //    4
52  UINT8 Revision;             //    8
53  UINT8 Checksum;             //    9
54  UINT8 OemId[6];             //   10
55  UINT8 OemTableId[8];        //   16
56  UINT32 OemRevision;         //   24
57  UINT32 CreatorId;           //   28
58  UINT32 CreatorRevision;     //   32
59  UINT8 DefinitionBlock[1];   //   36
60} ACPI_DSDT;
61
62
63typedef struct {
64  UINT32 Signature;           //    0
65  UINT32 Length;              //    4
66  UINT8 Revision;             //    8
67  UINT8 Checksum;             //    9
68  UINT8 OemId[6];             //   10
69  UINT8 OemTableId[8];        //   16
70  UINT32 OemRevision;         //   24
71  UINT32 CreatorId;           //   28
72  UINT32 CreatorRevision;     //   32
73  UINT32 FirmwareCtrl;        //   36
74  UINT32 DSDT;                //   40
75  UINT8 Reserved;             //   44
76  UINT8 PreferredPmProfile;   //   45
77  UINT16 SciInt;              //   46
78  UINT32 SmiCmd;              //   48
79  UINT8 AcpiEnable;           //   52
80  UINT8 AcpiDisable;          //   53
81  UINT8 S4BiosReq;            //   54
82  UINT8 PStateCnt;            //   55
83  UINT32 Pm1aEvtBlk;          //   56
84  UINT32 Pm1bEvtBlk;          //   60
85  UINT32 Pm1aCntBlk;          //   64
86  UINT32 Pm1bCntBlk;          //   68
87  UINT32 Pm2CntBlk;           //   72
88  UINT32 PmTmrBlk;            //   76
89  UINT32 Gpe0Blk;             //   80
90  UINT32 Gpe1Blk;             //   84
91  UINT8 Pm1EvtLen;            //   88
92  UINT8 Pm1CntLen;            //   89
93  UINT8 PM2CntLen;            //   90
94  UINT8 PmTmrLen;             //   91
95  UINT8 Gpe0BlkLen;           //   92
96  UINT8 Gpe1BlkLen;           //   93
97  UINT8 Gpe1Base;             //   94
98  UINT8 CstCnt;               //   95
99  UINT16 PLvl2Lat;            //   96
100  UINT16 PLvl3Lat;            //   98
101  UINT16 FlushSize;           //  100
102  UINT16 FlushStride;         //  102
103  UINT8 DutyOffset;           //  104
104  UINT8 DutyWidth;            //  105
105  UINT8 DayAlrm;              //  106
106  UINT8 MonAlrm;              //  107
107  UINT8 Century;              //  108
108  UINT16 IapcBootArch;        //  109
109  UINT8 Reserved2;            //  111
110  UINT32 Flags;               //  112
111  UINT32 ResetReg[3];         //  116
112  UINT8 ResetValue;           //  128
113  UINT8 Reserved3[3];         //  129
114  UINT64 XFirmwareCtrl;       //  132
115  UINT64 XDsdt;               //  140
116  UINT32 XPm1aEvtBlk[3];      //  148
117  UINT32 XPm1bEvtBlk[3];      //  160
118  UINT32 XPm1aCntBlk[3];      //  172
119  UINT32 XPm1bCntBlk[3];      //  184
120  UINT32 XPm2CntBlk[3];       //  196
121  UINT32 XPmTmrBlk[3];        //  208
122  UINT32 XGpe0Blk[3];         //  220
123  UINT32 XGpe1Blk[3];         //  232
124} ACPI_FADT;
125
126
127typedef struct {
128  UINT32 Signature;
129  UINT32 Length;
130  UINT8 Revision;
131  UINT8 Checksum;
132  UINT8 OemId[6];
133  UINT8 OemTableId[8];
134  UINT32 OemRevision;
135  UINT32 CreatorId;
136  UINT32 CreatorRevision;
137  UINT32 Entry[1];
138} ACPI_RSDT;
139
140
141#pragma pack()
142
143
144typedef struct {
145  UINT32 Signature;
146  CONST CHAR8 * pTableName;
147  CONST CHAR16 * pWebPage;
148} TABLE_SIGNATURE;
149
150
151CONST TABLE_SIGNATURE mTableId[] = {
152  { DSDT_SIGNATURE, "DSDT", PAGE_ACPI_DSDT },
153  { FADT_SIGNATURE, "FADT", PAGE_ACPI_FADT }
154};
155
156
157/**
158  Locate the RSDT table
159
160  @return  Table address or NULL if not found
161
162**/
163CONST ACPI_RSDT *
164LocateRsdt (
165  VOID
166  )
167{
168  CONST EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER * pRsdp10b;
169  CONST EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER * pRsdp30;
170  CONST ACPI_RSDT * pRsdt;
171  EFI_STATUS Status;
172
173  //
174  //  Use for/break instead of goto
175  //
176  pRsdt = NULL;
177  for ( ; ; ) {
178    //
179    //  Locate the RSDT
180    //
181    Status = EfiGetSystemConfigurationTable ( &gEfiAcpiTableGuid, (VOID **)&pRsdp30 );
182    if ( !EFI_ERROR ( Status )) {
183      pRsdt = (ACPI_RSDT *)pRsdp30->RsdtAddress;
184    }
185    else {
186      Status = EfiGetSystemConfigurationTable (&gEfiAcpi10TableGuid, (VOID **)&pRsdp10b );
187      if ( EFI_ERROR ( Status )) {
188        break;
189      }
190      pRsdt = (ACPI_RSDT *)pRsdp10b->RsdtAddress;
191    }
192    break;
193  }
194
195  //
196  //  The entry was not found
197  //
198  return pRsdt;
199}
200
201
202/**
203  Locate the specified table
204
205  @param [in] Signature     Table signature
206
207  @return  Table address or NULL if not found
208
209**/
210CONST VOID *
211LocateTable (
212  IN UINT32 Signature
213  )
214{
215  CONST UINT32 * pEnd;
216  CONST UINT32 * pEntry;
217  CONST EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER * pRsdp10b;
218  CONST EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER * pRsdp30;
219  CONST ACPI_RSDT * pRsdt;
220  CONST UINT32 * pSignature;
221  EFI_STATUS Status;
222
223  //
224  //  Use for/break instead of goto
225  //
226  for ( ; ; ) {
227    //
228    //  Locate the RSDT
229    //
230    Status = EfiGetSystemConfigurationTable ( &gEfiAcpiTableGuid, (VOID **)&pRsdp30 );
231    if ( !EFI_ERROR ( Status )) {
232      pRsdt = (ACPI_RSDT *)pRsdp30->RsdtAddress;
233    }
234    else {
235      Status = EfiGetSystemConfigurationTable (&gEfiAcpi10TableGuid, (VOID **)&pRsdp10b );
236      if ( EFI_ERROR ( Status )) {
237        break;
238      }
239      pRsdt = (ACPI_RSDT *)pRsdp10b->RsdtAddress;
240    }
241
242    //
243    //  Walk the list of entries
244    //
245    pEntry = &pRsdt->Entry[ 0 ];
246    pEnd = &pEntry[(( pRsdt->Length - sizeof ( *pRsdt )) >> 2 ) + 1 ];
247    while ( pEnd > pEntry ) {
248      //
249      //  The entry is actually a 32-bit physical table address
250      //  The first entry in the table is the 32-bit table signature
251      //
252      pSignature = (UINT32 *)*pEntry;
253      if ( *pSignature == Signature ) {
254        return (CONST VOID *) *pEntry;
255      }
256
257      //
258      //  Set the next entry
259      //
260      pEntry++;
261    }
262    break;
263  }
264
265  //
266  //  The entry was not found
267  //
268  return NULL;
269}
270
271
272/**
273  Display a row containing a hex value
274
275  @param [in] SocketFD      The socket's file descriptor to add to the list.
276  @param [in] pPort         The WSDT_PORT structure address
277  @param [in] pName         Address of a zero terminated name string
278  @param [in] Length        Length in bytes
279  @param [in] pChar         Address of the first character
280
281  @retval EFI_SUCCESS       The request was successfully processed
282
283**/
284EFI_STATUS
285RowAnsiArray (
286  IN int SocketFD,
287  IN WSDT_PORT * pPort,
288  IN CONST CHAR8 * pName,
289  IN UINTN Length,
290  IN CONST CHAR8 * pChar
291  )
292{
293  CONST CHAR8 * pData;
294  CONST CHAR8 * pEnd;
295  EFI_STATUS Status;
296
297  DBG_ENTER ( );
298
299  //
300  //  Use for/break instead of goto
301  //
302  for ( ; ; ) {
303    //
304    //  Start the row
305    //
306    Status = HttpSendAnsiString ( SocketFD,
307                                  pPort,
308                                  "<tr><td>" );
309    if ( EFI_ERROR ( Status )) {
310      break;
311    }
312    Status = HttpSendAnsiString ( SocketFD,
313                                  pPort,
314                                  pName );
315    if ( EFI_ERROR ( Status )) {
316      break;
317    }
318    Status = HttpSendAnsiString ( SocketFD,
319                                  pPort,
320                                  "</td><td><code>" );
321    if ( EFI_ERROR ( Status )) {
322      break;
323    }
324
325    //
326    //  Display the characters
327    //
328    pData = pChar;
329    pEnd = &pChar[ Length ];
330    while ( pEnd > pData ) {
331      Status = HttpSendCharacter ( SocketFD,
332                                   pPort,
333                                   *pData++,
334                                   " " );
335      if ( EFI_ERROR ( Status )) {
336        break;
337      }
338    }
339    if ( EFI_ERROR ( Status )) {
340      break;
341    }
342
343    //
344    //  Display the byte values
345    //
346    Status = HttpSendAnsiString ( SocketFD,
347                                  pPort,
348                                  "<br/>0x" );
349    if ( EFI_ERROR ( Status )) {
350      break;
351    }
352    pData = pChar;
353    while ( pEnd > pData ) {
354      Status = HttpSendHexBits ( SocketFD,
355                                 pPort,
356                                 8,
357                                 *pData++ );
358      if ( EFI_ERROR ( Status )) {
359        break;
360      }
361      if ( pEnd > pData ) {
362        Status = HttpSendAnsiString ( SocketFD,
363                                      pPort,
364                                      " 0x" );
365        if ( EFI_ERROR ( Status )) {
366          break;
367        }
368      }
369    }
370
371    //
372    //  Terminate the row
373    //
374    Status = HttpSendAnsiString ( SocketFD,
375                                  pPort,
376                                  "</code></td></tr>\r\n" );
377    break;
378  }
379
380  //
381  //  Return the operation status
382  //
383  DBG_EXIT_STATUS ( Status );
384  return Status;
385}
386
387
388/**
389  Format a row with a list of bytes
390
391  @param [in] SocketFD      The socket's file descriptor to add to the list.
392  @param [in] pPort         The WSDT_PORT structure address
393  @param [in] pName         Zero terminated name string
394  @param [in] ByteCount     The number of bytes to display
395  @param [in] pData         Address of the byte array
396
397  @retval EFI_SUCCESS       The request was successfully processed
398
399**/
400EFI_STATUS
401RowBytes (
402  IN int SocketFD,
403  IN WSDT_PORT * pPort,
404  IN CHAR8 * pName,
405  IN UINTN ByteCount,
406  IN CONST UINT8 * pData
407  )
408{
409  CONST UINT8 * pEnd;
410  EFI_STATUS Status;
411
412  //
413  //  Use for/break instead of goto
414  //
415  for ( ; ; ) {
416    //
417    //  Start the row
418    //
419    Status = HttpSendAnsiString ( SocketFD,
420                                  pPort,
421                                  "<tr><td>" );
422    if ( EFI_ERROR ( Status )) {
423      break;
424    }
425
426    //
427    //  Display the field name
428    //
429    Status = HttpSendAnsiString ( SocketFD,
430                                  pPort,
431                                  pName );
432    if ( EFI_ERROR ( Status )) {
433      break;
434    }
435
436    //
437    //  Display the field value
438    //
439    Status = HttpSendAnsiString ( SocketFD,
440                                  pPort,
441                                  "</td><td><code>0x" );
442    if ( EFI_ERROR ( Status )) {
443      break;
444    }
445    pEnd = &pData[ ByteCount ];
446    while ( pEnd > pData ) {
447      Status = HttpSendHexBits ( SocketFD,
448                                 pPort,
449                                 8,
450                                 *pData++ );
451      if ( EFI_ERROR ( Status )) {
452        break;
453      }
454      if ( pEnd > pData ) {
455        Status = HttpSendAnsiString ( SocketFD,
456                                      pPort,
457                                      " 0x" );
458        if ( EFI_ERROR ( Status )) {
459          break;
460        }
461      }
462    }
463    if ( EFI_ERROR ( Status )) {
464      break;
465    }
466
467    //
468    //  Terminate the row
469    //
470    Status = HttpSendAnsiString ( SocketFD,
471                                  pPort,
472                                  "</code></td></tr>\r\n" );
473    break;
474  }
475
476  //
477  //  Return the operation status
478  //
479  return Status;
480}
481
482
483/**
484  Format a row with a list of bytes
485
486  @param [in] SocketFD      The socket's file descriptor to add to the list.
487  @param [in] pPort         The WSDT_PORT structure address
488  @param [in] pName         Zero terminated name string
489  @param [in] ByteCount     The number of bytes to display
490  @param [in] pData         Address of the byte array
491
492  @retval EFI_SUCCESS       The request was successfully processed
493
494**/
495EFI_STATUS
496RowDump (
497  IN int SocketFD,
498  IN WSDT_PORT * pPort,
499  IN CHAR8 * pName,
500  IN UINTN ByteCount,
501  IN CONST UINT8 * pData
502  )
503{
504  EFI_STATUS Status;
505
506  //
507  //  Use for/break instead of goto
508  //
509  for ( ; ; ) {
510    //
511    //  Start the row
512    //
513    Status = HttpSendAnsiString ( SocketFD,
514                                  pPort,
515                                  "<tr><td>" );
516    if ( EFI_ERROR ( Status )) {
517      break;
518    }
519
520    //
521    //  Display the field name
522    //
523    Status = HttpSendAnsiString ( SocketFD,
524                                  pPort,
525                                  pName );
526    if ( EFI_ERROR ( Status )) {
527      break;
528    }
529
530    //
531    //  Start the field value
532    //
533    Status = HttpSendAnsiString ( SocketFD,
534                                  pPort,
535                                  "</td><td>" );
536    if ( EFI_ERROR ( Status )) {
537      break;
538    }
539
540    //
541    //  Dump the buffer
542    //
543    Status = HttpSendDump ( SocketFD,
544                            pPort,
545                            ByteCount,
546                            pData );
547
548    //
549    //  Terminate the field value and row
550    //
551    Status = HttpSendAnsiString ( SocketFD,
552                                  pPort,
553                                  "</td></tr>\r\n" );
554    break;
555  }
556
557  //
558  //  Return the operation status
559  //
560  return Status;
561}
562
563
564/**
565  Format a row with a general address
566
567  @param [in] SocketFD      The socket's file descriptor to add to the list.
568  @param [in] pPort         The WSDT_PORT structure address
569  @param [in] pName         Zero terminated name string
570  @param [in] pAddr         Address of the general address buffer
571  @param [in] pWebPage      Zero terminated web page address
572
573  @retval EFI_SUCCESS       The request was successfully processed
574
575**/
576EFI_STATUS
577RowGenericAddress (
578  IN int SocketFD,
579  IN WSDT_PORT * pPort,
580  IN CHAR8 * pName,
581  IN CONST UINT32 * pAddr,
582  IN CONST CHAR16 * pWebPage
583  )
584{
585  CONST GENERIC_ADDRESS * pGenericAddress;
586  EFI_STATUS Status;
587
588  //
589  //  Use for/break instead of goto
590  //
591  for ( ; ; ) {
592    //
593    //  Start the row
594    //
595    Status = HttpSendAnsiString ( SocketFD,
596                                  pPort,
597                                  "<tr><td>" );
598    if ( EFI_ERROR ( Status )) {
599      break;
600    }
601
602    //
603    //  Display the field name
604    //
605    Status = HttpSendAnsiString ( SocketFD,
606                                  pPort,
607                                  pName );
608    if ( EFI_ERROR ( Status )) {
609      break;
610    }
611
612    //
613    //  Display the field value
614    //
615    Status = HttpSendAnsiString ( SocketFD,
616                                  pPort,
617                                  "</td><td><code>" );
618    if ( EFI_ERROR ( Status )) {
619      break;
620    }
621
622    //
623    //  Determine the type of address
624    //
625    pGenericAddress = (CONST GENERIC_ADDRESS *)pAddr;
626    if ( 0 == pGenericAddress->AddressSpaceId ) {
627      Status = HttpSendAnsiString ( SocketFD, pPort, "System Memory" );
628    }
629    else if ( 1 == pGenericAddress->AddressSpaceId ) {
630      Status = HttpSendAnsiString ( SocketFD, pPort, "I/O Space" );
631    }
632    else if ( 2 == pGenericAddress->AddressSpaceId ) {
633      Status = HttpSendAnsiString ( SocketFD, pPort, "PCI Configuration Space" );
634    }
635    else if ( 3 == pGenericAddress->AddressSpaceId ) {
636      Status = HttpSendAnsiString ( SocketFD, pPort, "Embedded Controller" );
637    }
638    else if ( 4 == pGenericAddress->AddressSpaceId ) {
639      Status = HttpSendAnsiString ( SocketFD, pPort, "SMBus" );
640    }
641    else if ( 0x7f == pGenericAddress->AddressSpaceId ) {
642      Status = HttpSendAnsiString ( SocketFD, pPort, "Functional Fixed Hardware" );
643    }
644    else if (( 0xc0 <= pGenericAddress->AddressSpaceId )
645      && ( 0xff >= pGenericAddress->AddressSpaceId )) {
646      Status = HttpSendAnsiString ( SocketFD, pPort, "OEM Defined" );
647    }
648    else {
649      Status = HttpSendAnsiString ( SocketFD, pPort, "Reserved" );
650    }
651    if ( EFI_ERROR ( Status )) {
652      break;
653    }
654    Status = HttpSendAnsiString ( SocketFD,
655                                  pPort,
656                                  "<br/>Register Bit Width: " );
657    if ( EFI_ERROR ( Status )) {
658      break;
659    }
660    Status = HttpSendValue ( SocketFD,
661                             pPort,
662                             pGenericAddress->RegisterBitWidth );
663    if ( EFI_ERROR ( Status )) {
664      break;
665    }
666    Status = HttpSendAnsiString ( SocketFD,
667                                  pPort,
668                                  "<br/>Register Bit Offset: " );
669    if ( EFI_ERROR ( Status )) {
670      break;
671    }
672    Status = HttpSendHexValue ( SocketFD,
673                                pPort,
674                                pGenericAddress->RegisterBitOffset );
675    if ( EFI_ERROR ( Status )) {
676      break;
677    }
678    Status = HttpSendAnsiString ( SocketFD,
679                                  pPort,
680                                  "<br/>Access Size: " );
681    if ( EFI_ERROR ( Status )) {
682      break;
683    }
684    Status = HttpSendValue ( SocketFD,
685                             pPort,
686                             pGenericAddress->AccessSize );
687    if ( EFI_ERROR ( Status )) {
688      break;
689    }
690    Status = HttpSendAnsiString ( SocketFD,
691                                  pPort,
692                                  "<br/>Address: " );
693    if ( EFI_ERROR ( Status )) {
694      break;
695    }
696
697    //
698    //  Add the web-page link if necessary
699    //
700    if ( NULL != pWebPage ) {
701      Status = HttpSendAnsiString ( SocketFD,
702                                    pPort,
703                                    "<a target=\"_blank\" href=\"" );
704      if ( EFI_ERROR ( Status )) {
705        break;
706      }
707      Status = HttpSendUnicodeString ( SocketFD,
708                                       pPort,
709                                       pWebPage );
710      if ( EFI_ERROR ( Status )) {
711        break;
712      }
713      Status = HttpSendAnsiString ( SocketFD,
714                                    pPort,
715                                    "\">" );
716      if ( EFI_ERROR ( Status )) {
717        break;
718      }
719    }
720
721    //
722    //  Display the address
723    //
724    Status = HttpSendAnsiString ( SocketFD,
725                                  pPort,
726                                  "0x" );
727    if ( EFI_ERROR ( Status )) {
728      break;
729    }
730    Status = HttpSendHexBits ( SocketFD,
731                               pPort,
732                               64,
733                               pGenericAddress->Address );
734    if ( EFI_ERROR ( Status )) {
735      break;
736    }
737
738    //
739    //  Finish the web-page link if necessary
740    //
741    if ( NULL != pWebPage ) {
742      Status = HttpSendAnsiString ( SocketFD,
743                                    pPort,
744                                    "</a>" );
745      if ( EFI_ERROR ( Status )) {
746        break;
747      }
748    }
749
750    //
751    //  Terminate the row
752    //
753    Status = HttpSendAnsiString ( SocketFD,
754                                  pPort,
755                                  "</code></td></tr>\r\n" );
756    break;
757  }
758
759  //
760  //  Return the operation status
761  //
762  return Status;
763}
764
765
766/**
767  Translate a table address into a web page
768
769  @param [in] pSignature      Address of the table signature
770  @param [out] ppTableName    Address to receive the table name address
771
772  @return  Zero terminated web page address or NULL if not found
773
774**/
775CONST CHAR16 *
776SignatureLookup (
777  IN UINT32 * pSignature,
778  OUT CONST CHAR8 ** ppTableName
779  )
780{
781  CONST TABLE_SIGNATURE * pTableId;
782  CONST TABLE_SIGNATURE * pEnd;
783  UINT32 Signature;
784
785  //
786  //  Walk the list of tables
787  //
788  Signature = *pSignature;
789  pTableId = &mTableId[ 0 ];
790  pEnd = &pTableId[ sizeof ( mTableId ) / sizeof ( mTableId[ 0 ])];
791  while ( pEnd > pTableId ) {
792    //
793    //  Attempt to locate the table signature
794    //
795    if ( pTableId->Signature == Signature ) {
796      //
797      //  The signature was found
798      //  Return the web page
799      //
800      *ppTableName = pTableId->pTableName;
801      return pTableId->pWebPage;
802    }
803
804    //
805    //  Set the next table
806    //
807    pTableId += 1;
808  }
809
810  //
811  //  The table was not found
812  //
813  *ppTableName = (CONST CHAR8 *)pSignature;
814  return NULL;
815}
816
817
818/**
819  Respond with the ACPI DSDT table
820
821  @param [in] SocketFD      The socket's file descriptor to add to the list.
822  @param [in] pPort         The WSDT_PORT structure address
823  @param [out] pbDone       Address to receive the request completion status
824
825  @retval EFI_SUCCESS       The request was successfully processed
826
827**/
828EFI_STATUS
829AcpiDsdtPage (
830  IN int SocketFD,
831  IN WSDT_PORT * pPort,
832  OUT BOOLEAN * pbDone
833  )
834{
835  CONST ACPI_DSDT * pDsdt;
836  CONST ACPI_FADT * pFadt;
837  EFI_STATUS Status;
838
839  DBG_ENTER ( );
840
841  //
842  //  Send the DADT page
843  //
844  for ( ; ; ) {
845    //
846    //  Locate the DADT
847    //
848    pFadt = (ACPI_FADT *)LocateTable ( FADT_SIGNATURE );
849    if ( NULL == pFadt ) {
850      Status = EFI_NOT_FOUND;
851      break;
852    }
853    pDsdt = (VOID *)(UINTN)pFadt->XDsdt;
854
855    //
856    //  Send the page and table header
857    //
858    Status = TableHeader ( SocketFD, pPort, L"DSDT - Differentiated System Description Table", pDsdt );
859    if ( EFI_ERROR ( Status )) {
860      break;
861    }
862
863    //
864    //  Display the DSDT header
865    //
866    Status = RowAnsiArray ( SocketFD,
867                            pPort,
868                            "Signature",
869                            sizeof ( pDsdt->Signature ),
870                            (CHAR8 *)&pDsdt->Signature );
871    if ( EFI_ERROR ( Status )) {
872      break;
873    }
874    Status = RowDecimalValue ( SocketFD,
875                               pPort,
876                               "Length",
877                               pDsdt->Length );
878    if ( EFI_ERROR ( Status )) {
879      break;
880    }
881    Status = RowDecimalValue ( SocketFD,
882                               pPort,
883                               "Revision",
884                               pDsdt->Revision );
885    if ( EFI_ERROR ( Status )) {
886      break;
887    }
888    Status = RowHexValue ( SocketFD,
889                           pPort,
890                           "Checksum",
891                           pDsdt->Checksum,
892                           NULL );
893    if ( EFI_ERROR ( Status )) {
894      break;
895    }
896    Status = RowAnsiArray ( SocketFD,
897                            pPort,
898                            "OEMID",
899                            sizeof ( pDsdt->OemId ),
900                            (CONST CHAR8 *)&pDsdt->OemId[ 0 ]);
901    if ( EFI_ERROR ( Status )) {
902      break;
903    }
904    Status = RowAnsiArray ( SocketFD,
905                            pPort,
906                            "OEM Table ID",
907                            sizeof ( pDsdt->OemTableId ),
908                            (CONST CHAR8 *)&pDsdt->OemTableId[ 0 ]);
909    if ( EFI_ERROR ( Status )) {
910      break;
911    }
912    Status = RowRevision ( SocketFD,
913                           pPort,
914                           "OEM Revision",
915                           pDsdt->OemRevision );
916    if ( EFI_ERROR ( Status )) {
917      break;
918    }
919    Status = RowAnsiArray ( SocketFD,
920                            pPort,
921                            "Creator ID",
922                            sizeof ( pDsdt->CreatorId ),
923                            (CHAR8 *)&pDsdt->CreatorId );
924    if ( EFI_ERROR ( Status )) {
925      break;
926    }
927    Status = RowRevision ( SocketFD,
928                           pPort,
929                           "Creator Revision",
930                           pDsdt->CreatorRevision );
931    if ( EFI_ERROR ( Status )) {
932      break;
933    }
934
935    //
936    //  Display the data from the DSDT
937    //
938    Status = RowDump ( SocketFD,
939                       pPort,
940                       "Definition Block",
941                       pDsdt->Length - sizeof ( *pDsdt ) + 1,
942                       &pDsdt->DefinitionBlock[0]);
943    if ( EFI_ERROR ( Status )) {
944      break;
945    }
946
947    //
948    //  Build the table trailer
949    //
950    Status = TableTrailer ( SocketFD,
951                            pPort,
952                            pbDone );
953    break;
954  }
955
956  //
957  //  Return the operation status
958  //
959  DBG_EXIT_STATUS ( Status );
960  return Status;
961}
962
963
964/**
965  Respond with the ACPI FADT table
966
967  @param [in] SocketFD      The socket's file descriptor to add to the list.
968  @param [in] pPort         The WSDT_PORT structure address
969  @param [out] pbDone       Address to receive the request completion status
970
971  @retval EFI_SUCCESS       The request was successfully processed
972
973**/
974EFI_STATUS
975AcpiFadtPage (
976  IN int SocketFD,
977  IN WSDT_PORT * pPort,
978  OUT BOOLEAN * pbDone
979  )
980{
981  CONST ACPI_FADT * pFadt;
982  EFI_STATUS Status;
983
984  DBG_ENTER ( );
985
986  //
987  //  Send the FADT page
988  //
989  for ( ; ; ) {
990    //
991    //  Locate the FADT
992    //
993    pFadt = (ACPI_FADT *)LocateTable ( FADT_SIGNATURE );
994    if ( NULL == pFadt ) {
995      Status = EFI_NOT_FOUND;
996      break;
997    }
998
999    //
1000    //  Send the page and table header
1001    //
1002    Status = TableHeader ( SocketFD, pPort, L"FADT - Fixed ACPI Description Table", pFadt );
1003    if ( EFI_ERROR ( Status )) {
1004      break;
1005    }
1006
1007    //
1008    //  Display the FSDT header
1009    //
1010    Status = RowAnsiArray ( SocketFD,
1011                            pPort,
1012                            "Signature",
1013                            sizeof ( pFadt->Signature ),
1014                            (CHAR8 *)&pFadt->Signature );
1015    if ( EFI_ERROR ( Status )) {
1016      break;
1017    }
1018    Status = RowDecimalValue ( SocketFD,
1019                               pPort,
1020                               "Length",
1021                               pFadt->Length );
1022    if ( EFI_ERROR ( Status )) {
1023      break;
1024    }
1025    Status = RowDecimalValue ( SocketFD,
1026                               pPort,
1027                               "Revision",
1028                               pFadt->Revision );
1029    if ( EFI_ERROR ( Status )) {
1030      break;
1031    }
1032    Status = RowHexValue ( SocketFD,
1033                           pPort,
1034                           "Checksum",
1035                           pFadt->Checksum,
1036                           NULL );
1037    if ( EFI_ERROR ( Status )) {
1038      break;
1039    }
1040    Status = RowAnsiArray ( SocketFD,
1041                            pPort,
1042                            "OEMID",
1043                            sizeof ( pFadt->OemId ),
1044                            (CONST CHAR8 *)&pFadt->OemId[ 0 ]);
1045    if ( EFI_ERROR ( Status )) {
1046      break;
1047    }
1048    Status = RowAnsiArray ( SocketFD,
1049                            pPort,
1050                            "OEM Table ID",
1051                            sizeof ( pFadt->OemTableId ),
1052                            (CONST CHAR8 *)&pFadt->OemTableId[ 0 ]);
1053    if ( EFI_ERROR ( Status )) {
1054      break;
1055    }
1056    Status = RowRevision ( SocketFD,
1057                           pPort,
1058                           "OEM Revision",
1059                           pFadt->OemRevision );
1060    if ( EFI_ERROR ( Status )) {
1061      break;
1062    }
1063    Status = RowAnsiArray ( SocketFD,
1064                            pPort,
1065                            "Creator ID",
1066                            sizeof ( pFadt->CreatorId ),
1067                            (CHAR8 *)&pFadt->CreatorId );
1068    if ( EFI_ERROR ( Status )) {
1069      break;
1070    }
1071    Status = RowRevision ( SocketFD,
1072                           pPort,
1073                           "Creator Revision",
1074                           pFadt->CreatorRevision );
1075    if ( EFI_ERROR ( Status )) {
1076      break;
1077    }
1078
1079    //
1080    //  Display the data from the FADT
1081    //
1082    Status = RowPointer ( SocketFD,
1083                          pPort,
1084                          "FIRMWARE_CTRL",
1085                          (CONST VOID *)pFadt->FirmwareCtrl,
1086                          NULL );
1087    if ( EFI_ERROR ( Status )) {
1088      break;
1089    }
1090    Status = RowPointer ( SocketFD,
1091                          pPort,
1092                          "DSDT",
1093                          (CONST VOID *)pFadt->DSDT,
1094                          ( pFadt->DSDT == pFadt->XDsdt ) ? PAGE_ACPI_DSDT : NULL );
1095    if ( EFI_ERROR ( Status )) {
1096      break;
1097    }
1098    Status = RowHexValue ( SocketFD,
1099                           pPort,
1100                           "Reserved",
1101                           pFadt->Reserved,
1102                           NULL );
1103    if ( EFI_ERROR ( Status )) {
1104      break;
1105    }
1106    Status = RowHexValue ( SocketFD,
1107                           pPort,
1108                           "Preferred_PM_Profile",
1109                           pFadt->PreferredPmProfile,
1110                           NULL );
1111    if ( EFI_ERROR ( Status )) {
1112      break;
1113    }
1114    Status = RowHexValue ( SocketFD,
1115                           pPort,
1116                           "SCI_INT",
1117                           pFadt->SciInt,
1118                           NULL );
1119    if ( EFI_ERROR ( Status )) {
1120      break;
1121    }
1122    Status = RowHexValue ( SocketFD,
1123                           pPort,
1124                           "SMI_CMD",
1125                           pFadt->SmiCmd,
1126                           NULL );
1127    if ( EFI_ERROR ( Status )) {
1128      break;
1129    }
1130    Status = RowHexValue ( SocketFD,
1131                           pPort,
1132                           "ACPI_ENABLE",
1133                           pFadt->AcpiEnable,
1134                           NULL );
1135    if ( EFI_ERROR ( Status )) {
1136      break;
1137    }
1138    Status = RowHexValue ( SocketFD,
1139                           pPort,
1140                           "ACPI_DISABLE",
1141                           pFadt->AcpiDisable,
1142                           NULL );
1143    if ( EFI_ERROR ( Status )) {
1144      break;
1145    }
1146    Status = RowHexValue ( SocketFD,
1147                           pPort,
1148                           "S4BIOS_REQ",
1149                           pFadt->S4BiosReq,
1150                           NULL );
1151    if ( EFI_ERROR ( Status )) {
1152      break;
1153    }
1154    Status = RowHexValue ( SocketFD,
1155                           pPort,
1156                           "PSTATE_CNT",
1157                           pFadt->PStateCnt,
1158                           NULL );
1159    if ( EFI_ERROR ( Status )) {
1160      break;
1161    }
1162    Status = RowHexValue ( SocketFD,
1163                           pPort,
1164                           "PM1a_EVT_BLK",
1165                           pFadt->Pm1aEvtBlk,
1166                           NULL );
1167    if ( EFI_ERROR ( Status )) {
1168      break;
1169    }
1170    Status = RowHexValue ( SocketFD,
1171                           pPort,
1172                           "PM1b_EVT_BLK",
1173                           pFadt->Pm1bEvtBlk,
1174                           NULL );
1175    if ( EFI_ERROR ( Status )) {
1176      break;
1177    }
1178    Status = RowHexValue ( SocketFD,
1179                           pPort,
1180                           "PM1a_CNT_BLK",
1181                           pFadt->Pm1aCntBlk,
1182                           NULL );
1183    if ( EFI_ERROR ( Status )) {
1184      break;
1185    }
1186    Status = RowHexValue ( SocketFD,
1187                           pPort,
1188                           "PM1b_CNT_BLK",
1189                           pFadt->Pm1bCntBlk,
1190                           NULL );
1191    if ( EFI_ERROR ( Status )) {
1192      break;
1193    }
1194    Status = RowHexValue ( SocketFD,
1195                           pPort,
1196                           "PM2_CNT_BLK",
1197                           pFadt->Pm2CntBlk,
1198                           NULL );
1199    if ( EFI_ERROR ( Status )) {
1200      break;
1201    }
1202    Status = RowHexValue ( SocketFD,
1203                           pPort,
1204                           "PM_TMR_BLK",
1205                           pFadt->PmTmrBlk,
1206                           NULL );
1207    if ( EFI_ERROR ( Status )) {
1208      break;
1209    }
1210
1211    Status = RowHexValue ( SocketFD,
1212                           pPort,
1213                           "GPE0_BLK",
1214                           pFadt->Gpe0Blk,
1215                           NULL );
1216    if ( EFI_ERROR ( Status )) {
1217      break;
1218    }
1219    Status = RowHexValue ( SocketFD,
1220                           pPort,
1221                           "GPE1_BLK",
1222                           pFadt->Gpe1Blk,
1223                           NULL );
1224    if ( EFI_ERROR ( Status )) {
1225      break;
1226    }
1227    Status = RowDecimalValue ( SocketFD,
1228                               pPort,
1229                               "PM1_EVT_LEN",
1230                               pFadt->Pm1EvtLen );
1231    if ( EFI_ERROR ( Status )) {
1232      break;
1233    }
1234    Status = RowDecimalValue ( SocketFD,
1235                               pPort,
1236                               "PM1_CNT_LEN",
1237                               pFadt->Pm1CntLen );
1238    if ( EFI_ERROR ( Status )) {
1239      break;
1240    }
1241    Status = RowDecimalValue ( SocketFD,
1242                               pPort,
1243                               "PM2_CNT_LEN",
1244                               pFadt->PM2CntLen );
1245    if ( EFI_ERROR ( Status )) {
1246      break;
1247    }
1248    Status = RowDecimalValue ( SocketFD,
1249                               pPort,
1250                               "PM_TMR_LEN",
1251                               pFadt->PmTmrLen );
1252    if ( EFI_ERROR ( Status )) {
1253      break;
1254    }
1255    Status = RowDecimalValue ( SocketFD,
1256                               pPort,
1257                               "GPE0_BLK_LEN",
1258                               pFadt->Gpe0BlkLen );
1259    if ( EFI_ERROR ( Status )) {
1260      break;
1261    }
1262    Status = RowDecimalValue ( SocketFD,
1263                               pPort,
1264                               "GPE1_BLK_LEN",
1265                               pFadt->Gpe1BlkLen );
1266    if ( EFI_ERROR ( Status )) {
1267      break;
1268    }
1269    Status = RowHexValue ( SocketFD,
1270                           pPort,
1271                           "GPE1_BASE",
1272                           pFadt->Gpe1Base,
1273                           NULL );
1274    if ( EFI_ERROR ( Status )) {
1275      break;
1276    }
1277    Status = RowDecimalValue ( SocketFD,
1278                               pPort,
1279                               "CST_CNT",
1280                               pFadt->CstCnt );
1281    if ( EFI_ERROR ( Status )) {
1282      break;
1283    }
1284    Status = RowHexValue ( SocketFD,
1285                           pPort,
1286                           "P_LVL2_LAT",
1287                           pFadt->PLvl2Lat,
1288                           NULL );
1289    if ( EFI_ERROR ( Status )) {
1290      break;
1291    }
1292    Status = RowHexValue ( SocketFD,
1293                           pPort,
1294                           "P_LVL3_LAT",
1295                           pFadt->PLvl3Lat,
1296                           NULL );
1297    if ( EFI_ERROR ( Status )) {
1298      break;
1299    }
1300    Status = RowDecimalValue ( SocketFD,
1301                               pPort,
1302                               "FLUSH_SIZE",
1303                               pFadt->FlushSize );
1304    if ( EFI_ERROR ( Status )) {
1305      break;
1306    }
1307    Status = RowDecimalValue ( SocketFD,
1308                               pPort,
1309                               "FLUSH_Stride",
1310                               pFadt->FlushStride );
1311    if ( EFI_ERROR ( Status )) {
1312      break;
1313    }
1314    Status = RowHexValue ( SocketFD,
1315                           pPort,
1316                           "DUTY_OFFSET",
1317                           pFadt->DutyOffset,
1318                           NULL );
1319    if ( EFI_ERROR ( Status )) {
1320      break;
1321    }
1322    Status = RowHexValue ( SocketFD,
1323                           pPort,
1324                           "DUTY_WIDTH",
1325                           pFadt->DutyWidth,
1326                           NULL );
1327    if ( EFI_ERROR ( Status )) {
1328      break;
1329    }
1330    Status = RowHexValue ( SocketFD,
1331                           pPort,
1332                           "DAY_ALRM",
1333                           pFadt->DayAlrm,
1334                           NULL );
1335    if ( EFI_ERROR ( Status )) {
1336      break;
1337    }
1338    Status = RowHexValue ( SocketFD,
1339                           pPort,
1340                           "MON_ALRM",
1341                           pFadt->MonAlrm,
1342                           NULL );
1343    if ( EFI_ERROR ( Status )) {
1344      break;
1345    }
1346    Status = RowHexValue ( SocketFD,
1347                           pPort,
1348                           "CENTURY",
1349                           pFadt->Century,
1350                           NULL );
1351    if ( EFI_ERROR ( Status )) {
1352      break;
1353    }
1354    Status = RowHexValue ( SocketFD,
1355                           pPort,
1356                           "IAPC_BOOT_ARCH",
1357                           pFadt->IapcBootArch,
1358                           NULL );
1359    if ( EFI_ERROR ( Status )) {
1360      break;
1361    }
1362    Status = RowHexValue ( SocketFD,
1363                           pPort,
1364                           "Reserved",
1365                           pFadt->Reserved2,
1366                           NULL );
1367    if ( EFI_ERROR ( Status )) {
1368      break;
1369    }
1370    Status = RowHexValue ( SocketFD,
1371                           pPort,
1372                           "Flags",
1373                           pFadt->Flags,
1374                           NULL );
1375    if ( EFI_ERROR ( Status )) {
1376      break;
1377    }
1378    Status = RowGenericAddress ( SocketFD,
1379                                 pPort,
1380                                 "RESET_REG",
1381                                 &pFadt->ResetReg[0],
1382                                 NULL );
1383    if ( EFI_ERROR ( Status )) {
1384      break;
1385    }
1386    Status = RowHexValue ( SocketFD,
1387                           pPort,
1388                           "RESET_VALUE",
1389                           pFadt->ResetValue,
1390                           NULL );
1391    if ( EFI_ERROR ( Status )) {
1392      break;
1393    }
1394    Status = RowHexValue ( SocketFD,
1395                           pPort,
1396                           "Reserved",
1397                           pFadt->Reserved3[0],
1398                           NULL );
1399    if ( EFI_ERROR ( Status )) {
1400      break;
1401    }
1402    Status = RowHexValue ( SocketFD,
1403                           pPort,
1404                           "Reserved",
1405                           pFadt->Reserved3[1],
1406                           NULL );
1407    if ( EFI_ERROR ( Status )) {
1408      break;
1409    }
1410    Status = RowHexValue ( SocketFD,
1411                           pPort,
1412                           "Reserved",
1413                           pFadt->Reserved3[2],
1414                           NULL );
1415    if ( EFI_ERROR ( Status )) {
1416      break;
1417    }
1418    Status = RowHexValue ( SocketFD,
1419                           pPort,
1420                           "X_FIRMWARE_CTRL",
1421                           pFadt->XFirmwareCtrl,
1422                           NULL );
1423    if ( EFI_ERROR ( Status )) {
1424      break;
1425    }
1426    Status = RowHexValue ( SocketFD,
1427                           pPort,
1428                           "X_DSDT",
1429                           pFadt->XDsdt,
1430                           PAGE_ACPI_DSDT );
1431    if ( EFI_ERROR ( Status )) {
1432      break;
1433    }
1434    Status = RowGenericAddress ( SocketFD,
1435                                 pPort,
1436                                 "X_PM1a_EVT_BLK",
1437                                 &pFadt->XPm1aEvtBlk[0],
1438                                 NULL );
1439    if ( EFI_ERROR ( Status )) {
1440      break;
1441    }
1442    Status = RowGenericAddress ( SocketFD,
1443                                 pPort,
1444                                 "X_PM1b_EVT_BLK",
1445                                 &pFadt->XPm1bEvtBlk[0],
1446                                 NULL );
1447    if ( EFI_ERROR ( Status )) {
1448      break;
1449    }
1450    Status = RowGenericAddress ( SocketFD,
1451                                 pPort,
1452                                 "X_PM1a_CNT_BLK",
1453                                 &pFadt->XPm1aCntBlk[0],
1454                                 NULL );
1455    if ( EFI_ERROR ( Status )) {
1456      break;
1457    }
1458    Status = RowGenericAddress ( SocketFD,
1459                                 pPort,
1460                                 "X_PM1b_CNT_BLK",
1461                                 &pFadt->XPm1bCntBlk[0],
1462                                 NULL );
1463    if ( EFI_ERROR ( Status )) {
1464      break;
1465    }
1466    Status = RowGenericAddress ( SocketFD,
1467                                 pPort,
1468                                 "X_PM2_CNT_BLK",
1469                                 &pFadt->XPm2CntBlk[0],
1470                                 NULL );
1471    if ( EFI_ERROR ( Status )) {
1472      break;
1473    }
1474    Status = RowGenericAddress ( SocketFD,
1475                                 pPort,
1476                                 "X_PM_TMR_BLK",
1477                                 &pFadt->XPmTmrBlk[0],
1478                                 NULL );
1479    if ( EFI_ERROR ( Status )) {
1480      break;
1481    }
1482    Status = RowGenericAddress ( SocketFD,
1483                                 pPort,
1484                                 "X_GPE0_BLK",
1485                                 &pFadt->XGpe0Blk[0],
1486                                 NULL );
1487    if ( EFI_ERROR ( Status )) {
1488      break;
1489    }
1490    Status = RowGenericAddress ( SocketFD,
1491                                 pPort,
1492                                 "X_GPE1_BLK",
1493                                 &pFadt->XGpe1Blk[0],
1494                                 NULL );
1495    if ( EFI_ERROR ( Status )) {
1496      break;
1497    }
1498
1499    //
1500    //  Build the table trailer
1501    //
1502    Status = TableTrailer ( SocketFD,
1503                            pPort,
1504                            pbDone );
1505    break;
1506  }
1507
1508  //
1509  //  Return the operation status
1510  //
1511  DBG_EXIT_STATUS ( Status );
1512  return Status;
1513}
1514
1515
1516/**
1517  Respond with the ACPI RSDP 1.0b table
1518
1519  @param [in] SocketFD      The socket's file descriptor to add to the list.
1520  @param [in] pPort         The WSDT_PORT structure address
1521  @param [out] pbDone       Address to receive the request completion status
1522
1523  @retval EFI_SUCCESS       The request was successfully processed
1524
1525**/
1526EFI_STATUS
1527AcpiRsdp10Page (
1528  IN int SocketFD,
1529  IN WSDT_PORT * pPort,
1530  OUT BOOLEAN * pbDone
1531  )
1532{
1533  CONST EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER * pRsdp10b;
1534  EFI_STATUS Status;
1535
1536  DBG_ENTER ( );
1537
1538  //
1539  //  Send the RSDP page
1540  //
1541  for ( ; ; ) {
1542    //
1543    //  Locate the RSDP
1544    //
1545    Status = EfiGetSystemConfigurationTable ( &gEfiAcpi10TableGuid, (VOID **) &pRsdp10b );
1546    if ( EFI_ERROR ( Status )) {
1547      break;
1548    }
1549
1550    //
1551    //  Send the page and table header
1552    //
1553    Status = TableHeader ( SocketFD, pPort, L"RSDP - ACPI 1.0b Root System Description Pointer", pRsdp10b );
1554    if ( EFI_ERROR ( Status )) {
1555      break;
1556    }
1557
1558    //
1559    //  Display the RSDP
1560    //
1561    Status = RowAnsiArray ( SocketFD,
1562                            pPort,
1563                            "Signature",
1564                            sizeof ( pRsdp10b->Signature ),
1565                            (CHAR8 *)&pRsdp10b->Signature );
1566    if ( EFI_ERROR ( Status )) {
1567      break;
1568    }
1569    Status = RowHexValue ( SocketFD,
1570                           pPort,
1571                           "Checksum",
1572                           pRsdp10b->Checksum,
1573                           NULL );
1574    if ( EFI_ERROR ( Status )) {
1575      break;
1576    }
1577    Status = RowAnsiArray ( SocketFD,
1578                            pPort,
1579                            "OemId",
1580                            sizeof ( pRsdp10b->OemId ),
1581                            (CONST CHAR8 *)&pRsdp10b->OemId[ 0 ]);
1582    if ( EFI_ERROR ( Status )) {
1583      break;
1584    }
1585    Status = RowHexValue ( SocketFD,
1586                           pPort,
1587                           "Reserved",
1588                           pRsdp10b->Reserved,
1589                           NULL );
1590    if ( EFI_ERROR ( Status )) {
1591      break;
1592    }
1593    Status = RowPointer ( SocketFD,
1594                          pPort,
1595                          "RsdtAddress",
1596                          (VOID *)pRsdp10b->RsdtAddress,
1597                          PAGE_ACPI_RSDT );
1598    if ( EFI_ERROR ( Status )) {
1599      break;
1600    }
1601
1602    //
1603    //  Build the table trailer
1604    //
1605    Status = TableTrailer ( SocketFD,
1606                            pPort,
1607                            pbDone );
1608    break;
1609  }
1610
1611  //
1612  //  Return the operation status
1613  //
1614  DBG_EXIT_STATUS ( Status );
1615  return Status;
1616}
1617
1618
1619/**
1620  Respond with the ACPI RSDP 3.0 table
1621
1622  @param [in] SocketFD      The socket's file descriptor to add to the list.
1623  @param [in] pPort         The WSDT_PORT structure address
1624  @param [out] pbDone       Address to receive the request completion status
1625
1626  @retval EFI_SUCCESS       The request was successfully processed
1627
1628**/
1629EFI_STATUS
1630AcpiRsdp30Page (
1631  IN int SocketFD,
1632  IN WSDT_PORT * pPort,
1633  OUT BOOLEAN * pbDone
1634  )
1635{
1636  CONST EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER * pRsdp30;
1637  EFI_STATUS Status;
1638
1639  DBG_ENTER ( );
1640
1641  //
1642  //  Send the RSDP page
1643  //
1644  for ( ; ; ) {
1645    //
1646    //  Locate the RSDP
1647    //
1648    Status = EfiGetSystemConfigurationTable ( &gEfiAcpiTableGuid, (VOID **) &pRsdp30 );
1649    if ( EFI_ERROR ( Status )) {
1650      break;
1651    }
1652
1653    //
1654    //  Send the page and table header
1655    //
1656    Status = TableHeader ( SocketFD, pPort, L"RSDP - ACPI 3.0 Root System Description Pointer", pRsdp30 );
1657    if ( EFI_ERROR ( Status )) {
1658      break;
1659    }
1660
1661    //
1662    //  Display the RSDP
1663    //
1664    Status = RowAnsiArray ( SocketFD,
1665                            pPort,
1666                            "Signature",
1667                            sizeof ( pRsdp30->Signature ),
1668                            (CHAR8 *)&pRsdp30->Signature );
1669    if ( EFI_ERROR ( Status )) {
1670      break;
1671    }
1672    Status = RowHexValue ( SocketFD,
1673                           pPort,
1674                           "Checksum",
1675                           pRsdp30->Checksum,
1676                           NULL );
1677    if ( EFI_ERROR ( Status )) {
1678      break;
1679    }
1680    Status = RowAnsiArray ( SocketFD,
1681                            pPort,
1682                            "OemId",
1683                            sizeof ( pRsdp30->OemId ),
1684                            (CONST CHAR8 *)&pRsdp30->OemId[ 0 ]);
1685    if ( EFI_ERROR ( Status )) {
1686      break;
1687    }
1688    Status = RowHexValue ( SocketFD,
1689                           pPort,
1690                           "Revision",
1691                           pRsdp30->Revision,
1692                           NULL );
1693    if ( EFI_ERROR ( Status )) {
1694      break;
1695    }
1696    Status = RowPointer ( SocketFD,
1697                          pPort,
1698                          "RsdtAddress",
1699                          (VOID *)pRsdp30->RsdtAddress,
1700                          PAGE_ACPI_RSDT );
1701    if ( EFI_ERROR ( Status )) {
1702      break;
1703    }
1704    Status = RowDecimalValue ( SocketFD,
1705                               pPort,
1706                               "Length",
1707                               pRsdp30->Length );
1708    if ( EFI_ERROR ( Status )) {
1709      break;
1710    }
1711    Status = RowPointer ( SocketFD,
1712                          pPort,
1713                          "XsdtAddress",
1714                          (VOID *)(UINTN)pRsdp30->XsdtAddress,
1715                          NULL );
1716    if ( EFI_ERROR ( Status )) {
1717      break;
1718    }
1719    Status = RowHexValue ( SocketFD,
1720                           pPort,
1721                           "ExtendedChecksum",
1722                           pRsdp30->ExtendedChecksum,
1723                           NULL );
1724    if ( EFI_ERROR ( Status )) {
1725      break;
1726    }
1727    Status = RowBytes ( SocketFD,
1728                        pPort,
1729                        "Reserved",
1730                        sizeof ( pRsdp30->Reserved ),
1731                        &pRsdp30->Reserved[ 0 ]);
1732    if ( EFI_ERROR ( Status )) {
1733      break;
1734    }
1735
1736    //
1737    //  Build the table trailer
1738    //
1739    Status = TableTrailer ( SocketFD,
1740                            pPort,
1741                            pbDone );
1742    break;
1743  }
1744
1745  //
1746  //  Return the operation status
1747  //
1748  DBG_EXIT_STATUS ( Status );
1749  return Status;
1750}
1751
1752
1753/**
1754  Respond with the ACPI RSDT table
1755
1756  @param [in] SocketFD      The socket's file descriptor to add to the list.
1757  @param [in] pPort         The WSDT_PORT structure address
1758  @param [out] pbDone       Address to receive the request completion status
1759
1760  @retval EFI_SUCCESS       The request was successfully processed
1761
1762**/
1763EFI_STATUS
1764AcpiRsdtPage (
1765  IN int SocketFD,
1766  IN WSDT_PORT * pPort,
1767  OUT BOOLEAN * pbDone
1768  )
1769{
1770  CONST UINT32 * pEnd;
1771  CONST UINT32 * pEntry;
1772  CONST ACPI_RSDT * pRsdt;
1773  CONST CHAR8 * pTableName;
1774  CONST CHAR16 * pWebPage;
1775  EFI_STATUS Status;
1776  UINT32 TableName[ 2 ];
1777
1778  DBG_ENTER ( );
1779
1780  //
1781  //  Send the RSDT page
1782  //
1783  for ( ; ; ) {
1784    //
1785    //  Locate the RSDT
1786    //
1787    pRsdt = LocateRsdt ( );
1788    if ( NULL == pRsdt ) {
1789      Status = EFI_NOT_FOUND;
1790      break;
1791    }
1792
1793    //
1794    //  Send the page and table header
1795    //
1796    Status = TableHeader ( SocketFD, pPort, L"RSDT - ACPI Root System Description Table", pRsdt );
1797    if ( EFI_ERROR ( Status )) {
1798      break;
1799    }
1800
1801    //
1802    //  Display the RSDT
1803    //
1804    Status = RowAnsiArray ( SocketFD,
1805                            pPort,
1806                            "Signature",
1807                            sizeof ( pRsdt->Signature ),
1808                            (CHAR8 *)&pRsdt->Signature );
1809    if ( EFI_ERROR ( Status )) {
1810      break;
1811    }
1812    Status = RowDecimalValue ( SocketFD,
1813                               pPort,
1814                               "Length",
1815                               pRsdt->Length );
1816    if ( EFI_ERROR ( Status )) {
1817      break;
1818    }
1819    Status = RowDecimalValue ( SocketFD,
1820                               pPort,
1821                               "Revision",
1822                               pRsdt->Revision );
1823    if ( EFI_ERROR ( Status )) {
1824      break;
1825    }
1826    Status = RowHexValue ( SocketFD,
1827                           pPort,
1828                           "Checksum",
1829                           pRsdt->Checksum,
1830                           NULL );
1831    if ( EFI_ERROR ( Status )) {
1832      break;
1833    }
1834    Status = RowAnsiArray ( SocketFD,
1835                            pPort,
1836                            "OEMID",
1837                            sizeof ( pRsdt->OemId ),
1838                            (CONST CHAR8 *)&pRsdt->OemId[ 0 ]);
1839    if ( EFI_ERROR ( Status )) {
1840      break;
1841    }
1842    Status = RowAnsiArray ( SocketFD,
1843                            pPort,
1844                            "OEM Table ID",
1845                            sizeof ( pRsdt->OemTableId ),
1846                            (CONST CHAR8 *)&pRsdt->OemTableId[ 0 ]);
1847    if ( EFI_ERROR ( Status )) {
1848      break;
1849    }
1850    Status = RowRevision ( SocketFD,
1851                           pPort,
1852                           "OEM Revision",
1853                           pRsdt->OemRevision );
1854    if ( EFI_ERROR ( Status )) {
1855      break;
1856    }
1857    Status = RowAnsiArray ( SocketFD,
1858                            pPort,
1859                            "Creator ID",
1860                            sizeof ( pRsdt->CreatorId ),
1861                            (CHAR8 *)&pRsdt->CreatorId );
1862    if ( EFI_ERROR ( Status )) {
1863      break;
1864    }
1865    Status = RowRevision ( SocketFD,
1866                           pPort,
1867                           "Creator Revision",
1868                           pRsdt->CreatorRevision );
1869    if ( EFI_ERROR ( Status )) {
1870      break;
1871    }
1872
1873    //
1874    //  Walk the list of entries
1875    //
1876    pEntry = &pRsdt->Entry[ 0 ];
1877    pEnd = &pEntry[(( pRsdt->Length - sizeof ( *pRsdt )) >> 2 ) + 1 ];
1878    TableName[ 1 ] = 0;
1879    while ( pEnd > pEntry ) {
1880      //
1881      //  The entry is actually a 32-bit physical table address
1882      //  The first entry in the table is the 32-bit table signature
1883      //
1884      TableName[ 0 ] = *(UINT32 *)*pEntry;
1885      pWebPage = SignatureLookup ( &TableName[ 0 ], &pTableName );
1886
1887      //
1888      //  Display the table address
1889      //
1890      Status = RowPointer ( SocketFD,
1891                            pPort,
1892                            pTableName,
1893                            (VOID *)*pEntry,
1894                            pWebPage );
1895      if ( EFI_ERROR ( Status )) {
1896        break;
1897      }
1898      pEntry++;
1899    }
1900    if ( EFI_ERROR ( Status )) {
1901      break;
1902    }
1903
1904    //
1905    //  Build the table trailer
1906    //
1907    Status = TableTrailer ( SocketFD,
1908                            pPort,
1909                            pbDone );
1910    break;
1911  }
1912
1913  //
1914  //  Return the operation status
1915  //
1916  DBG_EXIT_STATUS ( Status );
1917  return Status;
1918}
1919
1920
1921