1 /**
2 @file
3 Display the system table
4
5 Copyright (c) 2011-2012, Intel Corporation
6 All rights reserved. This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
10
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14 **/
15
16 #include <WebServer.h>
17
18
19 /**
20 Display the EFI Table Header
21
22 @param [in] SocketFD The socket's file descriptor to add to the list.
23 @param [in] pPort The WSDT_PORT structure address
24 @param [in] pHeader Address of the EFI_TABLE_HEADER structure
25
26 @retval EFI_SUCCESS The request was successfully processed
27
28 **/
29 EFI_STATUS
EfiTableHeader(IN int SocketFD,IN WSDT_PORT * pPort,IN EFI_TABLE_HEADER * pHeader)30 EfiTableHeader (
31 IN int SocketFD,
32 IN WSDT_PORT * pPort,
33 IN EFI_TABLE_HEADER * pHeader
34 )
35 {
36 EFI_STATUS Status;
37
38 DBG_ENTER ( );
39
40 //
41 // Send the handles page
42 //
43 for ( ; ; ) {
44 ///
45 /// A 64-bit signature that identifies the type of table that follows.
46 /// Unique signatures have been generated for the EFI System Table,
47 /// the EFI Boot Services Table, and the EFI Runtime Services Table.
48 ///
49 Status = RowHexValue ( SocketFD,
50 pPort,
51 "Hdr.Signature",
52 pHeader->Signature,
53 NULL );
54 if ( EFI_ERROR ( Status )) {
55 break;
56 }
57
58 ///
59 /// The revision of the EFI Specification to which this table
60 /// conforms. The upper 16 bits of this field contain the major
61 /// revision value, and the lower 16 bits contain the minor revision
62 /// value. The minor revision values are limited to the range of 00..99.
63 ///
64 Status = RowRevision ( SocketFD,
65 pPort,
66 "Hdr.Revision",
67 pHeader->Revision );
68 if ( EFI_ERROR ( Status )) {
69 break;
70 }
71
72 ///
73 /// The size, in bytes, of the entire table including the EFI_TABLE_HEADER.
74 ///
75 Status = RowDecimalValue ( SocketFD,
76 pPort,
77 "Hdr.HeaderSize",
78 pHeader->HeaderSize );
79 if ( EFI_ERROR ( Status )) {
80 break;
81 }
82
83 ///
84 /// The 32-bit CRC for the entire table. This value is computed by
85 /// setting this field to 0, and computing the 32-bit CRC for HeaderSize bytes.
86 ///
87 Status = RowHexValue ( SocketFD,
88 pPort,
89 "Hdr.CRC",
90 pHeader->CRC32,
91 NULL );
92 if ( EFI_ERROR ( Status )) {
93 break;
94 }
95
96 ///
97 /// Reserved field that must be set to 0.
98 ///
99 Status = RowHexValue ( SocketFD,
100 pPort,
101 "Hdr.Reserved",
102 pHeader->Reserved,
103 NULL );
104 break;
105 }
106
107 //
108 // Return the operation status
109 //
110 DBG_EXIT_STATUS ( Status );
111 return Status;
112 }
113
114
115 /**
116 Display a row containing a decimal value
117
118 @param [in] SocketFD The socket's file descriptor to add to the list.
119 @param [in] pPort The WSDT_PORT structure address
120 @param [in] pName Address of a zero terminated name string
121 @param [in] Value The value to display
122
123 @retval EFI_SUCCESS The request was successfully processed
124
125 **/
126 EFI_STATUS
RowDecimalValue(IN int SocketFD,IN WSDT_PORT * pPort,IN CONST CHAR8 * pName,IN UINT64 Value)127 RowDecimalValue (
128 IN int SocketFD,
129 IN WSDT_PORT * pPort,
130 IN CONST CHAR8 * pName,
131 IN UINT64 Value
132 )
133 {
134 EFI_STATUS Status;
135
136 DBG_ENTER ( );
137
138 //
139 // Use for/break instead of goto
140 //
141 for ( ; ; ) {
142 Status = HttpSendAnsiString ( SocketFD,
143 pPort,
144 "<tr><td>" );
145 if ( EFI_ERROR ( Status )) {
146 break;
147 }
148 Status = HttpSendAnsiString ( SocketFD,
149 pPort,
150 pName );
151 if ( EFI_ERROR ( Status )) {
152 break;
153 }
154 Status = HttpSendAnsiString ( SocketFD,
155 pPort,
156 "</td><td><code>" );
157 if ( EFI_ERROR ( Status )) {
158 break;
159 }
160 Status = HttpSendValue ( SocketFD,
161 pPort,
162 Value );
163 if ( EFI_ERROR ( Status )) {
164 break;
165 }
166 Status = HttpSendAnsiString ( SocketFD,
167 pPort,
168 "</code></td></tr>\r\n" );
169 break;
170 }
171
172 //
173 // Return the operation status
174 //
175 DBG_EXIT_STATUS ( Status );
176 return Status;
177 }
178
179
180 /**
181 Display a row containing a hex value
182
183 @param [in] SocketFD The socket's file descriptor to add to the list.
184 @param [in] pPort The WSDT_PORT structure address
185 @param [in] pName Address of a zero terminated name string
186 @param [in] Value The value to display
187 @param [in] pWebPage Address of a zero terminated web page name
188
189 @retval EFI_SUCCESS The request was successfully processed
190
191 **/
192 EFI_STATUS
RowHexValue(IN int SocketFD,IN WSDT_PORT * pPort,IN CONST CHAR8 * pName,IN UINT64 Value,IN CONST CHAR16 * pWebPage)193 RowHexValue (
194 IN int SocketFD,
195 IN WSDT_PORT * pPort,
196 IN CONST CHAR8 * pName,
197 IN UINT64 Value,
198 IN CONST CHAR16 * pWebPage
199 )
200 {
201 EFI_STATUS Status;
202
203 DBG_ENTER ( );
204
205 //
206 // Use for/break instead of goto
207 //
208 for ( ; ; ) {
209 Status = HttpSendAnsiString ( SocketFD,
210 pPort,
211 "<tr><td>" );
212 if ( EFI_ERROR ( Status )) {
213 break;
214 }
215 Status = HttpSendAnsiString ( SocketFD,
216 pPort,
217 pName );
218 if ( EFI_ERROR ( Status )) {
219 break;
220 }
221 Status = HttpSendAnsiString ( SocketFD,
222 pPort,
223 "</td><td><code>0x" );
224 if ( EFI_ERROR ( Status )) {
225 break;
226 }
227 if ( NULL != pWebPage ) {
228 Status = HttpSendAnsiString ( SocketFD,
229 pPort,
230 "<a target=\"_blank\" href=\"" );
231 if ( EFI_ERROR ( Status )) {
232 break;
233 }
234 Status = HttpSendUnicodeString ( SocketFD,
235 pPort,
236 pWebPage );
237 if ( EFI_ERROR ( Status )) {
238 break;
239 }
240 Status = HttpSendAnsiString ( SocketFD,
241 pPort,
242 "\">" );
243 if ( EFI_ERROR ( Status )) {
244 break;
245 }
246 }
247 Status = HttpSendHexValue ( SocketFD,
248 pPort,
249 Value );
250 if ( EFI_ERROR ( Status )) {
251 break;
252 }
253 if ( NULL != pWebPage ) {
254 Status = HttpSendAnsiString ( SocketFD,
255 pPort,
256 "</a>" );
257 if ( EFI_ERROR ( Status )) {
258 break;
259 }
260 }
261 Status = HttpSendAnsiString ( SocketFD,
262 pPort,
263 "</code></td></tr>\r\n" );
264 break;
265 }
266
267 //
268 // Return the operation status
269 //
270 DBG_EXIT_STATUS ( Status );
271 return Status;
272 }
273
274
275 /**
276 Display a row containing a pointer
277
278 @param [in] SocketFD The socket's file descriptor to add to the list.
279 @param [in] pPort The WSDT_PORT structure address
280 @param [in] pName Address of a zero terminated name string
281 @param [in] pAddress The address to display
282 @param [in] pWebPage Address of a zero terminated web page name
283
284 @retval EFI_SUCCESS The request was successfully processed
285
286 **/
287 EFI_STATUS
RowPointer(IN int SocketFD,IN WSDT_PORT * pPort,IN CONST CHAR8 * pName,IN CONST VOID * pAddress,IN CONST CHAR16 * pWebPage)288 RowPointer (
289 IN int SocketFD,
290 IN WSDT_PORT * pPort,
291 IN CONST CHAR8 * pName,
292 IN CONST VOID * pAddress,
293 IN CONST CHAR16 * pWebPage
294 )
295 {
296 EFI_STATUS Status;
297
298 DBG_ENTER ( );
299
300 //
301 // Use for/break instead of goto
302 //
303 for ( ; ; ) {
304 Status = HttpSendAnsiString ( SocketFD,
305 pPort,
306 "<tr><td>" );
307 if ( EFI_ERROR ( Status )) {
308 break;
309 }
310 Status = HttpSendAnsiString ( SocketFD,
311 pPort,
312 pName );
313 if ( EFI_ERROR ( Status )) {
314 break;
315 }
316 Status = HttpSendAnsiString ( SocketFD,
317 pPort,
318 "</td><td><code>" );
319 if ( EFI_ERROR ( Status )) {
320 break;
321 }
322 if ( NULL != pWebPage ) {
323 Status = HttpSendAnsiString ( SocketFD,
324 pPort,
325 "<a target=\"_blank\" href=\"" );
326 if ( EFI_ERROR ( Status )) {
327 break;
328 }
329 Status = HttpSendUnicodeString ( SocketFD,
330 pPort,
331 pWebPage );
332 if ( EFI_ERROR ( Status )) {
333 break;
334 }
335 Status = HttpSendAnsiString ( SocketFD,
336 pPort,
337 "\">" );
338 if ( EFI_ERROR ( Status )) {
339 break;
340 }
341 }
342 Status = HttpSendAnsiString ( SocketFD,
343 pPort,
344 "0x" );
345 if ( EFI_ERROR ( Status )) {
346 break;
347 }
348 Status = HttpSendHexBits ( SocketFD,
349 pPort,
350 sizeof ( pAddress ) * 8,
351 (UINT64)(UINTN)pAddress );
352 if ( EFI_ERROR ( Status )) {
353 break;
354 }
355 if ( NULL != pWebPage ) {
356 Status = HttpSendAnsiString ( SocketFD,
357 pPort,
358 "</a>" );
359 if ( EFI_ERROR ( Status )) {
360 break;
361 }
362 }
363 Status = HttpSendAnsiString ( SocketFD,
364 pPort,
365 "</code></td></tr>\r\n" );
366 break;
367 }
368
369 //
370 // Return the operation status
371 //
372 DBG_EXIT_STATUS ( Status );
373 return Status;
374 }
375
376
377 /**
378 Display a row containing a revision
379
380 @param [in] SocketFD The socket's file descriptor to add to the list.
381 @param [in] pPort The WSDT_PORT structure address
382 @param [in] pName Address of a zero terminated name string
383 @param [in] Revision The revision to display
384
385 @retval EFI_SUCCESS The request was successfully processed
386
387 **/
388 EFI_STATUS
RowRevision(IN int SocketFD,IN WSDT_PORT * pPort,IN CONST CHAR8 * pName,IN UINT32 Revision)389 RowRevision (
390 IN int SocketFD,
391 IN WSDT_PORT * pPort,
392 IN CONST CHAR8 * pName,
393 IN UINT32 Revision
394 )
395 {
396 EFI_STATUS Status;
397
398 DBG_ENTER ( );
399
400 //
401 // Use for/break instead of goto
402 //
403 for ( ; ; ) {
404 Status = HttpSendAnsiString ( SocketFD,
405 pPort,
406 "<tr><td>" );
407 if ( EFI_ERROR ( Status )) {
408 break;
409 }
410 Status = HttpSendAnsiString ( SocketFD,
411 pPort,
412 pName );
413 if ( EFI_ERROR ( Status )) {
414 break;
415 }
416 Status = HttpSendAnsiString ( SocketFD,
417 pPort,
418 "</td><td><code>" );
419 if ( EFI_ERROR ( Status )) {
420 break;
421 }
422 Status = HttpSendValue ( SocketFD,
423 pPort,
424 Revision >> 16 );
425 if ( EFI_ERROR ( Status )) {
426 break;
427 }
428 Status = HttpSendByte ( SocketFD,
429 pPort,
430 '.' );
431 if ( EFI_ERROR ( Status )) {
432 break;
433 }
434 Status = HttpSendValue ( SocketFD,
435 pPort,
436 Revision & 0xFFFF );
437 if ( EFI_ERROR ( Status )) {
438 break;
439 }
440 Status = HttpSendAnsiString ( SocketFD,
441 pPort,
442 "</code></td></tr>\r\n" );
443 break;
444 }
445
446 //
447 // Return the operation status
448 //
449 DBG_EXIT_STATUS ( Status );
450 return Status;
451 }
452
453
454 /**
455 Display a row containing a unicode string
456
457 @param [in] SocketFD The socket's file descriptor to add to the list.
458 @param [in] pPort The WSDT_PORT structure address
459 @param [in] pName Address of a zero terminated name string
460 @param [in] pString Address of a zero terminated unicode string
461
462 @retval EFI_SUCCESS The request was successfully processed
463
464 **/
465 EFI_STATUS
RowUnicodeString(IN int SocketFD,IN WSDT_PORT * pPort,IN CONST CHAR8 * pName,IN CONST CHAR16 * pString)466 RowUnicodeString (
467 IN int SocketFD,
468 IN WSDT_PORT * pPort,
469 IN CONST CHAR8 * pName,
470 IN CONST CHAR16 * pString
471 )
472 {
473 EFI_STATUS Status;
474
475 DBG_ENTER ( );
476
477 //
478 // Use for/break instead of goto
479 //
480 for ( ; ; ) {
481 Status = HttpSendAnsiString ( SocketFD,
482 pPort,
483 "<tr><td>" );
484 if ( EFI_ERROR ( Status )) {
485 break;
486 }
487 Status = HttpSendAnsiString ( SocketFD,
488 pPort,
489 pName );
490 if ( EFI_ERROR ( Status )) {
491 break;
492 }
493 Status = HttpSendAnsiString ( SocketFD,
494 pPort,
495 "</td><td>" );
496 if ( EFI_ERROR ( Status )) {
497 break;
498 }
499 Status = HttpSendUnicodeString ( SocketFD,
500 pPort,
501 pString );
502 if ( EFI_ERROR ( Status )) {
503 break;
504 }
505 Status = HttpSendAnsiString ( SocketFD,
506 pPort,
507 "</td></tr>\r\n" );
508 break;
509 }
510
511 //
512 // Return the operation status
513 //
514 DBG_EXIT_STATUS ( Status );
515 return Status;
516 }
517
518
519 /**
520 Start the table page
521
522 @param [in] SocketFD The socket's file descriptor to add to the list.
523 @param [in] pPort The WSDT_PORT structure address
524 @param [in] pName Address of a zero terminated name string
525 @param [in] pTable Address of the table
526
527 @retval EFI_SUCCESS The request was successfully processed
528
529 **/
530 EFI_STATUS
TableHeader(IN int SocketFD,IN WSDT_PORT * pPort,IN CONST CHAR16 * pName,IN CONST VOID * pTable)531 TableHeader (
532 IN int SocketFD,
533 IN WSDT_PORT * pPort,
534 IN CONST CHAR16 * pName,
535 IN CONST VOID * pTable
536 )
537 {
538 EFI_STATUS Status;
539
540 DBG_ENTER ( );
541
542 //
543 // Use for/break instead of goto
544 //
545 for ( ; ; ) {
546 //
547 // Send the page header
548 //
549 Status = HttpPageHeader ( SocketFD, pPort, pName );
550 if ( EFI_ERROR ( Status )) {
551 break;
552 }
553
554 //
555 // Build the table header
556 //
557 Status = HttpSendAnsiString ( SocketFD,
558 pPort,
559 "<h1>" );
560 if ( EFI_ERROR ( Status )) {
561 break;
562 }
563 Status = HttpSendUnicodeString ( SocketFD,
564 pPort,
565 pName );
566 if ( EFI_ERROR ( Status )) {
567 break;
568 }
569 if ( NULL != pTable ) {
570 Status = HttpSendAnsiString ( SocketFD,
571 pPort,
572 ": 0x" );
573 if ( EFI_ERROR ( Status )) {
574 break;
575 }
576 Status = HttpSendHexBits ( SocketFD,
577 pPort,
578 sizeof ( pTable ) * 8,
579 (UINT64)(UINTN)pTable );
580 if ( EFI_ERROR ( Status )) {
581 break;
582 }
583 }
584 Status = HttpSendAnsiString ( SocketFD,
585 pPort,
586 "</h1>\r\n"
587 "<table border=\"1\">\r\n"
588 " <tr bgcolor=\"c0c0ff\"><th>Field Name</th><th>Value</th></tr>\r\n" );
589 break;
590 }
591
592 //
593 // Return the operation status
594 //
595 DBG_EXIT_STATUS ( Status );
596 return Status;
597 }
598
599
600 /**
601 End the table page
602
603 @param [in] SocketFD The socket's file descriptor to add to the list.
604 @param [in] pPort The WSDT_PORT structure address
605 @param [out] pbDone Address to receive the request completion status
606
607 @retval EFI_SUCCESS The request was successfully processed
608
609 **/
610 EFI_STATUS
TableTrailer(IN int SocketFD,IN WSDT_PORT * pPort,OUT BOOLEAN * pbDone)611 TableTrailer (
612 IN int SocketFD,
613 IN WSDT_PORT * pPort,
614 OUT BOOLEAN *pbDone
615 )
616 {
617 EFI_STATUS Status;
618
619 DBG_ENTER ( );
620
621 //
622 // Use for/break instead of goto
623 //
624 for ( ; ; ) {
625 //
626 // Build the table trailer
627 //
628 Status = HttpSendAnsiString ( SocketFD,
629 pPort,
630 "</table>\r\n" );
631 if ( EFI_ERROR ( Status )) {
632 break;
633 }
634
635 //
636 // Send the page trailer
637 //
638 Status = HttpPageTrailer ( SocketFD, pPort, pbDone );
639 break;
640 }
641
642 //
643 // Return the operation status
644 //
645 DBG_EXIT_STATUS ( Status );
646 return Status;
647 }
648
649
650 /**
651 Respond with the system table
652
653 @param [in] SocketFD The socket's file descriptor to add to the list.
654 @param [in] pPort The WSDT_PORT structure address
655 @param [out] pbDone Address to receive the request completion status
656
657 @retval EFI_SUCCESS The request was successfully processed
658
659 **/
660 EFI_STATUS
SystemTablePage(IN int SocketFD,IN WSDT_PORT * pPort,OUT BOOLEAN * pbDone)661 SystemTablePage (
662 IN int SocketFD,
663 IN WSDT_PORT * pPort,
664 OUT BOOLEAN * pbDone
665 )
666 {
667 EFI_STATUS Status;
668
669 DBG_ENTER ( );
670
671 //
672 // Send the system table page
673 //
674 for ( ; ; ) {
675 //
676 // Send the page and table header
677 //
678 Status = TableHeader ( SocketFD, pPort, L"System Table", gST );
679 if ( EFI_ERROR ( Status )) {
680 break;
681 }
682
683 ///
684 /// The table header for the EFI System Table.
685 ///
686 Status = EfiTableHeader ( SocketFD,
687 pPort,
688 &gST->Hdr );
689 if ( EFI_ERROR ( Status )) {
690 break;
691 }
692
693 ///
694 /// A pointer to a null terminated string that identifies the vendor
695 /// that produces the system firmware for the platform.
696 ///
697 Status = RowUnicodeString ( SocketFD,
698 pPort,
699 "FirmwareVendor",
700 gST->FirmwareVendor );
701 if ( EFI_ERROR ( Status )) {
702 break;
703 }
704
705 ///
706 /// A firmware vendor specific value that identifies the revision
707 /// of the system firmware for the platform.
708 ///
709 Status = RowRevision ( SocketFD,
710 pPort,
711 "FirmwareRevision",
712 gST->FirmwareRevision );
713 if ( EFI_ERROR ( Status )) {
714 break;
715 }
716
717 ///
718 /// The handle for the active console input device. This handle must support
719 /// EFI_SIMPLE_TEXT_INPUT_PROTOCOL and EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.
720 ///
721 Status = RowPointer ( SocketFD,
722 pPort,
723 "ConsoleInHandle",
724 (VOID *)gST->ConsoleInHandle,
725 NULL );
726 if ( EFI_ERROR ( Status )) {
727 break;
728 }
729
730 ///
731 /// A pointer to the EFI_SIMPLE_TEXT_INPUT_PROTOCOL interface that is
732 /// associated with ConsoleInHandle.
733 ///
734 Status = RowPointer ( SocketFD,
735 pPort,
736 "ConIn",
737 (VOID *)gST->ConIn,
738 NULL );
739 if ( EFI_ERROR ( Status )) {
740 break;
741 }
742
743 ///
744 /// The handle for the active console output device.
745 ///
746 Status = RowPointer ( SocketFD,
747 pPort,
748 "ConsoleOutHandle",
749 (VOID *)gST->ConsoleOutHandle,
750 NULL );
751 if ( EFI_ERROR ( Status )) {
752 break;
753 }
754
755 ///
756 /// A pointer to the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL interface
757 /// that is associated with ConsoleOutHandle.
758 ///
759 Status = RowPointer ( SocketFD,
760 pPort,
761 "ConOut",
762 (VOID *)gST->ConOut,
763 NULL );
764 if ( EFI_ERROR ( Status )) {
765 break;
766 }
767
768 ///
769 /// The handle for the active standard error console device.
770 /// This handle must support the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.
771 ///
772 Status = RowPointer ( SocketFD,
773 pPort,
774 "StandardErrorHandle",
775 (VOID *)gST->StandardErrorHandle,
776 NULL );
777 if ( EFI_ERROR ( Status )) {
778 break;
779 }
780
781 ///
782 /// A pointer to the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL interface
783 /// that is associated with StandardErrorHandle.
784 ///
785 Status = RowPointer ( SocketFD,
786 pPort,
787 "StdErr",
788 (VOID *)gST->StdErr,
789 NULL );
790 if ( EFI_ERROR ( Status )) {
791 break;
792 }
793
794 ///
795 /// A pointer to the EFI Runtime Services Table.
796 ///
797 Status = RowPointer ( SocketFD,
798 pPort,
799 "RuntimeServices",
800 (VOID *)gST->RuntimeServices,
801 PAGE_RUNTIME_SERVICES_TABLE );
802
803 ///
804 /// A pointer to the EFI Boot Services Table.
805 ///
806 Status = RowPointer ( SocketFD,
807 pPort,
808 "BootServices",
809 (VOID *)gST->BootServices,
810 PAGE_BOOT_SERVICES_TABLE );
811 if ( EFI_ERROR ( Status )) {
812 break;
813 }
814
815 ///
816 /// The number of system configuration tables in the buffer ConfigurationTable.
817 ///
818 Status = RowDecimalValue ( SocketFD,
819 pPort,
820 "NumberOfTableEntries",
821 gST->NumberOfTableEntries );
822 if ( EFI_ERROR ( Status )) {
823 break;
824 }
825
826 ///
827 /// A pointer to the system configuration tables.
828 /// The number of entries in the table is NumberOfTableEntries.
829 ///
830 Status = RowPointer ( SocketFD,
831 pPort,
832 "ConfigurationTable",
833 (VOID *)gST->ConfigurationTable,
834 PAGE_CONFIGURATION_TABLE );
835 if ( EFI_ERROR ( Status )) {
836 break;
837 }
838
839 //
840 // Build the table trailer
841 //
842 Status = TableTrailer ( SocketFD,
843 pPort,
844 pbDone );
845 break;
846 }
847
848 //
849 // Return the operation status
850 //
851 DBG_EXIT_STATUS ( Status );
852 return Status;
853 }
854