1 /** @file
2 
3 Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
4 
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions
7 of the BSD License which accompanies this distribution.  The
8 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 #ifndef _LEGACY_BIOS_INTERFACE_
17 #define _LEGACY_BIOS_INTERFACE_
18 
19 
20 #include <FrameworkDxe.h>
21 #include <IndustryStandard/Pci.h>
22 #include <IndustryStandard/SmBios.h>
23 
24 #include <Guid/SmBios.h>
25 #include <Guid/Acpi.h>
26 #include <Guid/DxeServices.h>
27 #include <Guid/LegacyBios.h>
28 #include <Guid/StatusCodeDataTypeId.h>
29 #include <Guid/ImageAuthentication.h>
30 
31 #include <Protocol/BlockIo.h>
32 #include <Protocol/LoadedImage.h>
33 #include <Protocol/PciIo.h>
34 #include <Protocol/Cpu.h>
35 #include <Protocol/Timer.h>
36 #include <Protocol/IsaIo.h>
37 #include <Protocol/LegacyRegion2.h>
38 #include <Protocol/SimpleTextIn.h>
39 #include <Protocol/LegacyInterrupt.h>
40 #include <Protocol/LegacyBios.h>
41 #include <Protocol/DiskInfo.h>
42 #include <Protocol/GenericMemoryTest.h>
43 #include <Protocol/LegacyBiosPlatform.h>
44 #include <Protocol/DevicePath.h>
45 #include <Protocol/Legacy8259.h>
46 #include <Protocol/PciRootBridgeIo.h>
47 
48 #include <Library/BaseLib.h>
49 #include <Library/DebugLib.h>
50 #include <Library/UefiLib.h>
51 #include <Library/BaseMemoryLib.h>
52 #include <Library/ReportStatusCodeLib.h>
53 #include <Library/UefiRuntimeServicesTableLib.h>
54 #include <Library/HobLib.h>
55 #include <Library/UefiDriverEntryPoint.h>
56 #include <Library/MemoryAllocationLib.h>
57 #include <Library/UefiBootServicesTableLib.h>
58 #include <Library/IoLib.h>
59 #include <Library/PcdLib.h>
60 #include <Library/DevicePathLib.h>
61 #include <Library/DxeServicesTableLib.h>
62 #include <Library/PeCoffLib.h>
63 #include <Library/CacheMaintenanceLib.h>
64 #include <Library/DebugAgentLib.h>
65 
66 //
67 // BUGBUG: This entry maybe changed to PCD in future and wait for
68 //         redesign of BDS library
69 //
70 #define MAX_BBS_ENTRIES 0x100
71 
72 //
73 // Thunk Status Codes
74 //   (These apply only to errors with the thunk and not to the code that was
75 //   thunked to.)
76 //
77 #define THUNK_OK              0x00
78 #define THUNK_ERR_A20_UNSUP   0x01
79 #define THUNK_ERR_A20_FAILED  0x02
80 
81 //
82 // Vector base definitions
83 //
84 //
85 // 8259 Hardware definitions
86 //
87 #define LEGACY_MODE_BASE_VECTOR_MASTER     0x08
88 #define LEGACY_MODE_BASE_VECTOR_SLAVE      0x70
89 
90 //
91 // The original PC used INT8-F for master PIC. Since these mapped over
92 // processor exceptions TIANO moved the master PIC to INT68-6F.
93 //
94 // The vector base for slave PIC is set as 0x70 for PC-AT compatibility.
95 //
96 #define PROTECTED_MODE_BASE_VECTOR_MASTER  0x68
97 #define PROTECTED_MODE_BASE_VECTOR_SLAVE   0x70
98 
99 //
100 // When we call CSM16 functions, some CSM16 use es:[offset + 0xabcd] to get data passed from CSM32,
101 // offset + 0xabcd could overflow which exceeds 0xFFFF which is invalid in real mode.
102 // So this will keep offset as small as possible to avoid offset overflow in real mode.
103 //
104 #define NORMALIZE_EFI_SEGMENT(_Adr)      (UINT16) (((UINTN) (_Adr)) >> 4)
105 #define NORMALIZE_EFI_OFFSET(_Adr)       (UINT16) (((UINT16) ((UINTN) (_Adr))) & 0xf)
106 
107 //
108 // Trace defines
109 //
110 //
111 #define LEGACY_BDA_TRACE    0x000
112 #define LEGACY_BIOS_TRACE   0x040
113 #define LEGACY_BOOT_TRACE   0x080
114 #define LEGACY_CMOS_TRACE   0x0C0
115 #define LEGACY_IDE_TRACE    0x100
116 #define LEGACY_MP_TRACE     0x140
117 #define LEGACY_PCI_TRACE    0x180
118 #define LEGACY_SIO_TRACE    0x1C0
119 
120 #define LEGACY_PCI_TRACE_000 LEGACY_PCI_TRACE + 0x00
121 #define LEGACY_PCI_TRACE_001 LEGACY_PCI_TRACE + 0x01
122 #define LEGACY_PCI_TRACE_002 LEGACY_PCI_TRACE + 0x02
123 #define LEGACY_PCI_TRACE_003 LEGACY_PCI_TRACE + 0x03
124 #define LEGACY_PCI_TRACE_004 LEGACY_PCI_TRACE + 0x04
125 #define LEGACY_PCI_TRACE_005 LEGACY_PCI_TRACE + 0x05
126 #define LEGACY_PCI_TRACE_006 LEGACY_PCI_TRACE + 0x06
127 #define LEGACY_PCI_TRACE_007 LEGACY_PCI_TRACE + 0x07
128 #define LEGACY_PCI_TRACE_008 LEGACY_PCI_TRACE + 0x08
129 #define LEGACY_PCI_TRACE_009 LEGACY_PCI_TRACE + 0x09
130 #define LEGACY_PCI_TRACE_00A LEGACY_PCI_TRACE + 0x0A
131 #define LEGACY_PCI_TRACE_00B LEGACY_PCI_TRACE + 0x0B
132 #define LEGACY_PCI_TRACE_00C LEGACY_PCI_TRACE + 0x0C
133 #define LEGACY_PCI_TRACE_00D LEGACY_PCI_TRACE + 0x0D
134 #define LEGACY_PCI_TRACE_00E LEGACY_PCI_TRACE + 0x0E
135 #define LEGACY_PCI_TRACE_00F LEGACY_PCI_TRACE + 0x0F
136 
137 #define BDA_VIDEO_MODE      0x49
138 
139 #define IDE_PI_REGISTER_PNE     BIT0
140 #define IDE_PI_REGISTER_SNE     BIT2
141 
142 typedef struct {
143   UINTN   PciSegment;
144   UINTN   PciBus;
145   UINTN   PciDevice;
146   UINTN   PciFunction;
147   UINT32  ShadowAddress;
148   UINT32  ShadowedSize;
149   UINT8   DiskStart;
150   UINT8   DiskEnd;
151 } ROM_INSTANCE_ENTRY;
152 
153 //
154 // Values for RealModeGdt
155 //
156 #if defined (MDE_CPU_IA32)
157 
158 #define NUM_REAL_GDT_ENTRIES  3
159 #define CONVENTIONAL_MEMORY_TOP 0xA0000   // 640 KB
160 #define INITIAL_VALUE_BELOW_1K  0x0
161 
162 #elif defined (MDE_CPU_X64)
163 
164 #define NUM_REAL_GDT_ENTRIES  8
165 #define CONVENTIONAL_MEMORY_TOP 0xA0000   // 640 KB
166 #define INITIAL_VALUE_BELOW_1K  0x0
167 
168 #elif defined (MDE_CPU_IPF)
169 
170 #define NUM_REAL_GDT_ENTRIES  3
171 #define CONVENTIONAL_MEMORY_TOP 0x80000   // 512 KB
172 #define INITIAL_VALUE_BELOW_1K  0xff
173 
174 #endif
175 
176 #pragma pack(1)
177 
178 //
179 // Define what a processor GDT looks like
180 //
181 typedef struct {
182   UINT32  LimitLo : 16;
183   UINT32  BaseLo : 16;
184   UINT32  BaseMid : 8;
185   UINT32  Type : 4;
186   UINT32  System : 1;
187   UINT32  Dpl : 2;
188   UINT32  Present : 1;
189   UINT32  LimitHi : 4;
190   UINT32  Software : 1;
191   UINT32  Reserved : 1;
192   UINT32  DefaultSize : 1;
193   UINT32  Granularity : 1;
194   UINT32  BaseHi : 8;
195 } GDT32;
196 
197 typedef struct {
198   UINT16  LimitLow;
199   UINT16  BaseLow;
200   UINT8   BaseMid;
201   UINT8   Attribute;
202   UINT8   LimitHi;
203   UINT8   BaseHi;
204 } GDT64;
205 
206 //
207 // Define what a processor descriptor looks like
208 // This data structure must be kept in sync with ASM STRUCT in Thunk.inc
209 //
210 typedef struct {
211   UINT16  Limit;
212   UINT64  Base;
213 } DESCRIPTOR64;
214 
215 typedef struct {
216   UINT16  Limit;
217   UINT32  Base;
218 } DESCRIPTOR32;
219 
220 //
221 // Low stub lay out
222 //
223 #define LOW_STACK_SIZE      (8 * 1024)  // 8k?
224 #define EFI_MAX_E820_ENTRY  100
225 #define FIRST_INSTANCE      1
226 #define NOT_FIRST_INSTANCE  0
227 
228 #if defined (MDE_CPU_IA32)
229 typedef struct {
230   //
231   // Space for the code
232   //  The address of Code is also the beginning of the relocated Thunk code
233   //
234   CHAR8                             Code[4096]; // ?
235   //
236   // The address of the Reverse Thunk code
237   //  Note that this member CONTAINS the address of the relocated reverse thunk
238   //  code unlike the member variable 'Code', which IS the address of the Thunk
239   //  code.
240   //
241   UINT32                            LowReverseThunkStart;
242 
243   //
244   // Data for the code (cs releative)
245   //
246   DESCRIPTOR32                      GdtDesc;          // Protected mode GDT
247   DESCRIPTOR32                      IdtDesc;          // Protected mode IDT
248   UINT32                            FlatSs;
249   UINT32                            FlatEsp;
250 
251   UINT32                            LowCodeSelector;  // Low code selector in GDT
252   UINT32                            LowDataSelector;  // Low data selector in GDT
253   UINT32                            LowStack;
254   DESCRIPTOR32                      RealModeIdtDesc;
255 
256   //
257   // real-mode GDT (temporary GDT with two real mode segment descriptors)
258   //
259   GDT32                             RealModeGdt[NUM_REAL_GDT_ENTRIES];
260   DESCRIPTOR32                      RealModeGdtDesc;
261 
262   //
263   // Members specifically for the reverse thunk
264   //  The RevReal* members are used to store the current state of real mode
265   //  before performing the reverse thunk.  The RevFlat* members must be set
266   //  before calling the reverse thunk assembly code.
267   //
268   UINT16                            RevRealDs;
269   UINT16                            RevRealSs;
270   UINT32                            RevRealEsp;
271   DESCRIPTOR32                      RevRealIdtDesc;
272   UINT16                            RevFlatDataSelector;  // Flat data selector in GDT
273   UINT32                            RevFlatStack;
274 
275   //
276   // A low memory stack
277   //
278   CHAR8                             Stack[LOW_STACK_SIZE];
279 
280   //
281   // Stack for flat mode after reverse thunk
282   // @bug    - This may no longer be necessary if the reverse thunk interface
283   //           is changed to have the flat stack in a different location.
284   //
285   CHAR8                             RevThunkStack[LOW_STACK_SIZE];
286 
287   //
288   // Legacy16 Init memory map info
289   //
290   EFI_TO_COMPATIBILITY16_INIT_TABLE EfiToLegacy16InitTable;
291 
292   EFI_TO_COMPATIBILITY16_BOOT_TABLE EfiToLegacy16BootTable;
293 
294   CHAR8                             InterruptRedirectionCode[32];
295   EFI_LEGACY_INSTALL_PCI_HANDLER    PciHandler;
296   EFI_DISPATCH_OPROM_TABLE          DispatchOpromTable;
297   BBS_TABLE                         BbsTable[MAX_BBS_ENTRIES];
298 } LOW_MEMORY_THUNK;
299 
300 #elif defined (MDE_CPU_X64)
301 
302 typedef struct {
303   //
304   // Space for the code
305   //  The address of Code is also the beginning of the relocated Thunk code
306   //
307   CHAR8                             Code[4096]; // ?
308 
309   //
310   // Data for the code (cs releative)
311   //
312   DESCRIPTOR64                      X64GdtDesc;          // Protected mode GDT
313   DESCRIPTOR64                      X64IdtDesc;          // Protected mode IDT
314   UINTN                             X64Ss;
315   UINTN                             X64Esp;
316 
317   UINTN                             RealStack;
318   DESCRIPTOR32                      RealModeIdtDesc;
319   DESCRIPTOR32                      RealModeGdtDesc;
320 
321   //
322   // real-mode GDT (temporary GDT with two real mode segment descriptors)
323   //
324   GDT64                             RealModeGdt[NUM_REAL_GDT_ENTRIES];
325   UINT64                            PageMapLevel4;
326 
327   //
328   // A low memory stack
329   //
330   CHAR8                             Stack[LOW_STACK_SIZE];
331 
332   //
333   // Legacy16 Init memory map info
334   //
335   EFI_TO_COMPATIBILITY16_INIT_TABLE EfiToLegacy16InitTable;
336 
337   EFI_TO_COMPATIBILITY16_BOOT_TABLE EfiToLegacy16BootTable;
338 
339   CHAR8                             InterruptRedirectionCode[32];
340   EFI_LEGACY_INSTALL_PCI_HANDLER    PciHandler;
341   EFI_DISPATCH_OPROM_TABLE          DispatchOpromTable;
342   BBS_TABLE                         BbsTable[MAX_BBS_ENTRIES];
343 } LOW_MEMORY_THUNK;
344 
345 #elif defined (MDE_CPU_IPF)
346 
347 typedef struct {
348   //
349   // Space for the code
350   //  The address of Code is also the beginning of the relocated Thunk code
351   //
352   CHAR8                             Code[4096]; // ?
353   //
354   // The address of the Reverse Thunk code
355   //  Note that this member CONTAINS the address of the relocated reverse thunk
356   //  code unlike the member variable 'Code', which IS the address of the Thunk
357   //  code.
358   //
359   UINT32                            LowReverseThunkStart;
360 
361   //
362   // Data for the code (cs releative)
363   //
364   DESCRIPTOR32                      GdtDesc;          // Protected mode GDT
365   DESCRIPTOR32                      IdtDesc;          // Protected mode IDT
366   UINT32                            FlatSs;
367   UINT32                            FlatEsp;
368 
369   UINT32                            LowCodeSelector;  // Low code selector in GDT
370   UINT32                            LowDataSelector;  // Low data selector in GDT
371   UINT32                            LowStack;
372   DESCRIPTOR32                      RealModeIdtDesc;
373 
374   //
375   // real-mode GDT (temporary GDT with two real mode segment descriptors)
376   //
377   GDT32                             RealModeGdt[NUM_REAL_GDT_ENTRIES];
378   DESCRIPTOR32                      RealModeGdtDesc;
379 
380   //
381   // Members specifically for the reverse thunk
382   //  The RevReal* members are used to store the current state of real mode
383   //  before performing the reverse thunk.  The RevFlat* members must be set
384   //  before calling the reverse thunk assembly code.
385   //
386   UINT16                            RevRealDs;
387   UINT16                            RevRealSs;
388   UINT32                            RevRealEsp;
389   DESCRIPTOR32                      RevRealIdtDesc;
390   UINT16                            RevFlatDataSelector;  // Flat data selector in GDT
391   UINT32                            RevFlatStack;
392 
393   //
394   // A low memory stack
395   //
396   CHAR8                             Stack[LOW_STACK_SIZE];
397 
398   //
399   // Stack for flat mode after reverse thunk
400   // @bug - This may no longer be necessary if the reverse thunk interface
401   //           is changed to have the flat stack in a different location.
402   //
403   CHAR8                             RevThunkStack[LOW_STACK_SIZE];
404 
405   //
406   // Legacy16 Init memory map info
407   //
408   EFI_TO_COMPATIBILITY16_INIT_TABLE EfiToLegacy16InitTable;
409 
410   EFI_TO_COMPATIBILITY16_BOOT_TABLE EfiToLegacy16BootTable;
411 
412   CHAR8                             InterruptRedirectionCode[32];
413   EFI_LEGACY_INSTALL_PCI_HANDLER    PciHandler;
414   EFI_DISPATCH_OPROM_TABLE          DispatchOpromTable;
415   BBS_TABLE                         BbsTable[MAX_BBS_ENTRIES];
416 } LOW_MEMORY_THUNK;
417 
418 #endif
419 
420 //
421 // PnP Expansion Header
422 //
423 typedef struct {
424   UINT32  PnpSignature;
425   UINT8   Revision;
426   UINT8   Length;
427   UINT16  NextHeader;
428   UINT8   Reserved1;
429   UINT8   Checksum;
430   UINT32  DeviceId;
431   UINT16  MfgPointer;
432   UINT16  ProductNamePointer;
433   UINT8   Class;
434   UINT8   SubClass;
435   UINT8   Interface;
436   UINT8   DeviceIndicators;
437   UINT16  Bcv;
438   UINT16  DisconnectVector;
439   UINT16  Bev;
440   UINT16  Reserved2;
441   UINT16  StaticResourceVector;
442 } LEGACY_PNP_EXPANSION_HEADER;
443 
444 typedef struct {
445   UINT8   PciSegment;
446   UINT8   PciBus;
447   UINT8   PciDevice;
448   UINT8   PciFunction;
449   UINT16  Vid;
450   UINT16  Did;
451   UINT16  SysSid;
452   UINT16  SVid;
453   UINT8   Class;
454   UINT8   SubClass;
455   UINT8   Interface;
456   UINT8   Reserved;
457   UINTN   RomStart;
458   UINTN   ManufacturerString;
459   UINTN   ProductNameString;
460 } LEGACY_ROM_AND_BBS_TABLE;
461 
462 //
463 // Structure how EFI has mapped a devices HDD drive numbers.
464 // Boot to EFI aware OS or shell requires this mapping when
465 // 16-bit CSM assigns drive numbers.
466 // This mapping is ignored booting to a legacy OS.
467 //
468 typedef struct {
469   UINT8 PciSegment;
470   UINT8 PciBus;
471   UINT8 PciDevice;
472   UINT8 PciFunction;
473   UINT8 StartDriveNumber;
474   UINT8 EndDriveNumber;
475 } LEGACY_EFI_HDD_TABLE;
476 
477 //
478 // This data is passed to Leacy16Boot
479 //
480 typedef enum {
481   EfiAcpiAddressRangeMemory   = 1,
482   EfiAcpiAddressRangeReserved = 2,
483   EfiAcpiAddressRangeACPI     = 3,
484   EfiAcpiAddressRangeNVS      = 4,
485   EfiAddressRangePersistentMemory = 7
486 } EFI_ACPI_MEMORY_TYPE;
487 
488 typedef struct {
489   UINT64                BaseAddr;
490   UINT64                Length;
491   EFI_ACPI_MEMORY_TYPE  Type;
492 } EFI_E820_ENTRY64;
493 
494 typedef struct {
495   UINT32                BassAddrLow;
496   UINT32                BaseAddrHigh;
497   UINT32                LengthLow;
498   UINT32                LengthHigh;
499   EFI_ACPI_MEMORY_TYPE  Type;
500 } EFI_E820_ENTRY;
501 
502 #pragma pack()
503 
504 extern BBS_TABLE           *mBbsTable;
505 
506 extern EFI_GENERIC_MEMORY_TEST_PROTOCOL *gGenMemoryTest;
507 
508 #define PORT_70 0x70
509 #define PORT_71 0x71
510 
511 #define CMOS_0A     0x0a  ///< Status register A
512 #define CMOS_0D     0x0d  ///< Status register D
513 #define CMOS_0E     0x0e  ///< Diagnostic Status
514 #define CMOS_0F     0x0f  ///< Shutdown status
515 #define CMOS_10     0x10  ///< Floppy type
516 #define CMOS_12     0x12  ///< IDE type
517 #define CMOS_14     0x14  ///< Same as BDA 40:10
518 #define CMOS_15     0x15  ///< Low byte of base memory in 1k increments
519 #define CMOS_16     0x16  ///< High byte of base memory in 1k increments
520 #define CMOS_17     0x17  ///< Low byte of 1MB+ memory in 1k increments - max 15 MB
521 #define CMOS_18     0x18  ///< High byte of 1MB+ memory in 1k increments - max 15 MB
522 #define CMOS_19     0x19  ///< C: extended drive type
523 #define CMOS_1A     0x1a  ///< D: extended drive type
524 #define CMOS_2E     0x2e  ///< Most significient byte of standard checksum
525 #define CMOS_2F     0x2f  ///< Least significient byte of standard checksum
526 #define CMOS_30     0x30  ///< CMOS 0x17
527 #define CMOS_31     0x31  ///< CMOS 0x18
528 #define CMOS_32     0x32  ///< Century byte
529 
530 //
531 // 8254 Timer registers
532 //
533 #define TIMER0_COUNT_PORT                         0x40
534 #define TIMER1_COUNT_PORT                         0x41
535 #define TIMER2_COUNT_PORT                         0x42
536 #define TIMER_CONTROL_PORT                        0x43
537 
538 //
539 // Timer 0, Read/Write LSB then MSB, Square wave output, binary count use.
540 //
541 #define TIMER0_CONTROL_WORD         0x36
542 
543 #define LEGACY_BIOS_INSTANCE_SIGNATURE  SIGNATURE_32 ('L', 'B', 'I', 'T')
544 typedef struct {
545   UINTN                             Signature;
546 
547   EFI_HANDLE                        Handle;
548   EFI_LEGACY_BIOS_PROTOCOL          LegacyBios;
549 
550   EFI_HANDLE                        ImageHandle;
551 
552   //
553   // CPU Architectural Protocol
554   //
555   EFI_CPU_ARCH_PROTOCOL             *Cpu;
556 
557   //
558   // Timer Architectural Protocol
559   //
560   EFI_TIMER_ARCH_PROTOCOL           *Timer;
561   BOOLEAN                           TimerUses8254;
562 
563   //
564   // Protocol to Lock and Unlock 0xc0000 - 0xfffff
565   //
566   EFI_LEGACY_REGION2_PROTOCOL       *LegacyRegion;
567 
568   EFI_LEGACY_BIOS_PLATFORM_PROTOCOL *LegacyBiosPlatform;
569 
570   //
571   // Interrupt control for thunk and PCI IRQ
572   //
573   EFI_LEGACY_8259_PROTOCOL          *Legacy8259;
574 
575   //
576   // PCI Interrupt PIRQ control
577   //
578   EFI_LEGACY_INTERRUPT_PROTOCOL     *LegacyInterrupt;
579 
580   //
581   // Generic Memory Test
582   //
583   EFI_GENERIC_MEMORY_TEST_PROTOCOL  *GenericMemoryTest;
584 
585   //
586   // TRUE if PCI Interupt Line registers have been programmed.
587   //
588   BOOLEAN                           PciInterruptLine;
589 
590   //
591   // Code space below 1MB needed by thunker to transition to real mode.
592   // Contains stack and real mode code fragments
593   //
594   LOW_MEMORY_THUNK                  *IntThunk;
595 
596   //
597   // Starting shadow address of the Legacy BIOS
598   //
599   UINT32                            BiosStart;
600   UINT32                            LegacyBiosImageSize;
601 
602   //
603   // Start of variables used by CsmItp.mac ITP macro file and/os LegacyBios
604   //
605   UINT8                             Dump[4];
606 
607   //
608   // $EFI Legacy16 code entry info in memory < 1 MB;
609   //
610   EFI_COMPATIBILITY16_TABLE         *Legacy16Table;
611   VOID                              *Legacy16InitPtr;
612   VOID                              *Legacy16BootPtr;
613   VOID                              *InternalIrqRoutingTable;
614   UINT32                            NumberIrqRoutingEntries;
615   VOID                              *BbsTablePtr;
616   VOID                              *HddTablePtr;
617   UINT32                            NumberHddControllers;
618 
619   //
620   // Cached copy of Legacy16 entry point
621   //
622   UINT16                            Legacy16CallSegment;
623   UINT16                            Legacy16CallOffset;
624 
625   //
626   // Returned from $EFI and passed in to OPROMS
627   //
628   UINT16                            PnPInstallationCheckSegment;
629   UINT16                            PnPInstallationCheckOffset;
630 
631   //
632   // E820 table
633   //
634   EFI_E820_ENTRY                    E820Table[EFI_MAX_E820_ENTRY];
635   UINT32                            NumberE820Entries;
636 
637   //
638   // True if legacy VGA INT 10h handler installed
639   //
640   BOOLEAN                           VgaInstalled;
641 
642   //
643   // Number of IDE drives
644   //
645   UINT8                             IdeDriveCount;
646 
647   //
648   // Current Free Option ROM space. An option ROM must NOT go past
649   // BiosStart.
650   //
651   UINT32                            OptionRom;
652 
653   //
654   // Save Legacy16 unexpected interrupt vector. Reprogram INT 68-6F from
655   // EFI values to legacy value just before boot.
656   //
657   UINT32                            BiosUnexpectedInt;
658   UINT32                            ThunkSavedInt[8];
659   UINT16                            ThunkSeg;
660   LEGACY_EFI_HDD_TABLE              *LegacyEfiHddTable;
661   UINT16                            LegacyEfiHddTableIndex;
662   UINT8                             DiskEnd;
663   UINT8                             Disk4075;
664   UINT16                            TraceIndex;
665   UINT16                            Trace[0x200];
666 
667   //
668   // Indicate that whether GenericLegacyBoot is entered or not
669   //
670   BOOLEAN                           LegacyBootEntered;
671 
672   //
673   // CSM16 PCI Interface Version
674   //
675   UINT16                            Csm16PciInterfaceVersion;
676 
677 } LEGACY_BIOS_INSTANCE;
678 
679 
680 #pragma pack(1)
681 
682 /*
683   40:00-01 Com1
684   40:02-03 Com2
685   40:04-05 Com3
686   40:06-07 Com4
687   40:08-09 Lpt1
688   40:0A-0B Lpt2
689   40:0C-0D Lpt3
690   40:0E-0E Ebda segment
691   40:10-11 MachineConfig
692   40:12    Bda12 - skip
693   40:13-14 MemSize below 1MB
694   40:15-16 Bda15_16 - skip
695   40:17    Keyboard Shift status
696   40:18-19 Bda18_19 - skip
697   40:1A-1B Key buffer head
698   40:1C-1D Key buffer tail
699   40:1E-3D Bda1E_3D- key buffer -skip
700   40:3E-3F FloppyData 3E = Calibration status 3F = Motor status
701   40:40    FloppyTimeout
702   40:41-74 Bda41_74 - skip
703   40:75    Number of HDD drives
704   40:76-77 Bda76_77 - skip
705   40:78-79 78 = Lpt1 timeout, 79 = Lpt2 timeout
706   40:7A-7B 7A = Lpt3 timeout, 7B = Lpt4 timeout
707   40:7C-7D 7C = Com1 timeout, 7D = Com2 timeout
708   40:7E-7F 7E = Com3 timeout, 7F = Com4 timeout
709   40:80-81 Pointer to start of key buffer
710   40:82-83 Pointer to end of key buffer
711   40:84-87 Bda84_87 - skip
712   40:88    HDD Data Xmit rate
713   40:89-8f skip
714   40:90    Floppy data rate
715   40:91-95 skip
716   40:96    Keyboard Status
717   40:97    LED Status
718   40:98-101 skip
719 */
720 typedef struct {
721   UINT16  Com1;
722   UINT16  Com2;
723   UINT16  Com3;
724   UINT16  Com4;
725   UINT16  Lpt1;
726   UINT16  Lpt2;
727   UINT16  Lpt3;
728   UINT16  Ebda;
729   UINT16  MachineConfig;
730   UINT8   Bda12;
731   UINT16  MemSize;
732   UINT8   Bda15_16[0x02];
733   UINT8   ShiftStatus;
734   UINT8   Bda18_19[0x02];
735   UINT16  KeyHead;
736   UINT16  KeyTail;
737   UINT16  Bda1E_3D[0x10];
738   UINT16  FloppyData;
739   UINT8   FloppyTimeout;
740   UINT8   Bda41_74[0x34];
741   UINT8   NumberOfDrives;
742   UINT8   Bda76_77[0x02];
743   UINT16  Lpt1_2Timeout;
744   UINT16  Lpt3_4Timeout;
745   UINT16  Com1_2Timeout;
746   UINT16  Com3_4Timeout;
747   UINT16  KeyStart;
748   UINT16  KeyEnd;
749   UINT8   Bda84_87[0x4];
750   UINT8   DataXmit;
751   UINT8   Bda89_8F[0x07];
752   UINT8   FloppyXRate;
753   UINT8   Bda91_95[0x05];
754   UINT8   KeyboardStatus;
755   UINT8   LedStatus;
756 } BDA_STRUC;
757 #pragma pack()
758 
759 #define LEGACY_BIOS_INSTANCE_FROM_THIS(this)  CR (this, LEGACY_BIOS_INSTANCE, LegacyBios, LEGACY_BIOS_INSTANCE_SIGNATURE)
760 
761 /**
762   Thunk to 16-bit real mode and execute a software interrupt with a vector
763   of BiosInt. Regs will contain the 16-bit register context on entry and
764   exit.
765 
766   @param  This    Protocol instance pointer.
767   @param  BiosInt Processor interrupt vector to invoke
768   @param  Regs    Register contexted passed into (and returned) from thunk to
769                   16-bit mode
770 
771   @retval FALSE   Thunk completed, and there were no BIOS errors in the target code.
772                   See Regs for status.
773   @retval TRUE     There was a BIOS erro in the target code.
774 
775 **/
776 BOOLEAN
777 EFIAPI
778 LegacyBiosInt86 (
779   IN  EFI_LEGACY_BIOS_PROTOCOL          *This,
780   IN  UINT8                             BiosInt,
781   IN  EFI_IA32_REGISTER_SET             *Regs
782   );
783 
784 
785 /**
786   Thunk to 16-bit real mode and call Segment:Offset. Regs will contain the
787   16-bit register context on entry and exit. Arguments can be passed on
788   the Stack argument
789 
790   @param  This                   Protocol instance pointer.
791   @param  Segment                Segemnt of 16-bit mode call
792   @param  Offset                 Offset of 16-bit mdoe call
793   @param  Regs                   Register contexted passed into (and returned) from
794                                  thunk to  16-bit mode
795   @param  Stack                  Caller allocated stack used to pass arguments
796   @param  StackSize              Size of Stack in bytes
797 
798   @retval FALSE                  Thunk completed, and there were no BIOS errors in
799                                  the target code. See Regs for status.
800   @retval TRUE                   There was a BIOS erro in the target code.
801 
802 **/
803 BOOLEAN
804 EFIAPI
805 LegacyBiosFarCall86 (
806   IN  EFI_LEGACY_BIOS_PROTOCOL          *This,
807   IN  UINT16                            Segment,
808   IN  UINT16                            Offset,
809   IN  EFI_IA32_REGISTER_SET             *Regs,
810   IN  VOID                              *Stack,
811   IN  UINTN                             StackSize
812   );
813 
814 
815 /**
816   Test to see if a legacy PCI ROM exists for this device. Optionally return
817   the Legacy ROM instance for this PCI device.
818 
819   @param  This                   Protocol instance pointer.
820   @param  PciHandle              The PCI PC-AT OPROM from this devices ROM BAR will
821                                  be loaded
822   @param  RomImage               Return the legacy PCI ROM for this device
823   @param  RomSize                Size of ROM Image
824   @param  Flags                  Indicates if ROM found and if PC-AT.
825 
826   @retval EFI_SUCCESS            Legacy Option ROM availible for this device
827   @retval EFI_UNSUPPORTED        Legacy Option ROM not supported.
828 
829 **/
830 EFI_STATUS
831 EFIAPI
832 LegacyBiosCheckPciRom (
833   IN  EFI_LEGACY_BIOS_PROTOCOL          *This,
834   IN  EFI_HANDLE                        PciHandle,
835   OUT VOID                              **RomImage, OPTIONAL
836   OUT UINTN                             *RomSize, OPTIONAL
837   OUT UINTN                             *Flags
838   );
839 
840 
841 /**
842   Assign drive number to legacy HDD drives prior to booting an EFI
843   aware OS so the OS can access drives without an EFI driver.
844   Note: BBS compliant drives ARE NOT available until this call by
845   either shell or EFI.
846 
847   @param  This                   Protocol instance pointer.
848   @param  BbsCount               Number of BBS_TABLE structures
849   @param  BbsTable               List BBS entries
850 
851   @retval EFI_SUCCESS            Drive numbers assigned
852 
853 **/
854 EFI_STATUS
855 EFIAPI
856 LegacyBiosPrepareToBootEfi (
857   IN EFI_LEGACY_BIOS_PROTOCOL         *This,
858   OUT UINT16                          *BbsCount,
859   OUT BBS_TABLE                       **BbsTable
860   );
861 
862 
863 /**
864   To boot from an unconventional device like parties and/or execute
865   HDD diagnostics.
866 
867   @param  This                   Protocol instance pointer.
868   @param  Attributes             How to interpret the other input parameters
869   @param  BbsEntry               The 0-based index into the BbsTable for the parent
870                                   device.
871   @param  BeerData               Pointer to the 128 bytes of ram BEER data.
872   @param  ServiceAreaData        Pointer to the 64 bytes of raw Service Area data.
873                                  The caller must provide a pointer to the specific
874                                  Service Area and not the start all Service Areas.
875  EFI_INVALID_PARAMETER if error. Does NOT return if no error.
876 
877 **/
878 EFI_STATUS
879 EFIAPI
880 LegacyBiosBootUnconventionalDevice (
881   IN EFI_LEGACY_BIOS_PROTOCOL         *This,
882   IN UDC_ATTRIBUTES                   Attributes,
883   IN UINTN                            BbsEntry,
884   IN VOID                             *BeerData,
885   IN VOID                             *ServiceAreaData
886   );
887 
888 
889 /**
890   Load a legacy PC-AT OPROM on the PciHandle device. Return information
891   about how many disks were added by the OPROM and the shadow address and
892   size. DiskStart & DiskEnd are INT 13h drive letters. Thus 0x80 is C:
893 
894   @param  This                   Protocol instance pointer.
895   @param  PciHandle              The PCI PC-AT OPROM from this devices ROM BAR will
896                                  be loaded. This value is NULL if RomImage is
897                                  non-NULL. This is the normal case.
898   @param  RomImage               A PCI PC-AT ROM image. This argument is non-NULL
899                                  if there is no hardware associated with the ROM
900                                  and thus no PciHandle, otherwise is must be NULL.
901                                  Example is PXE base code.
902   @param  Flags                  Indicates if ROM found and if PC-AT.
903   @param  DiskStart              Disk number of first device hooked by the ROM. If
904                                  DiskStart is the same as DiskEnd no disked were
905                                  hooked.
906   @param  DiskEnd                Disk number of the last device hooked by the ROM.
907   @param  RomShadowAddress       Shadow address of PC-AT ROM
908   @param  RomShadowedSize        Size of RomShadowAddress in bytes
909 
910   @retval EFI_SUCCESS            Legacy ROM loaded for this device
911   @retval EFI_INVALID_PARAMETER  PciHandle not found
912   @retval EFI_UNSUPPORTED        There is no PCI ROM in the ROM BAR or no onboard
913                                  ROM
914 
915 **/
916 EFI_STATUS
917 EFIAPI
918 LegacyBiosInstallPciRom (
919   IN  EFI_LEGACY_BIOS_PROTOCOL          * This,
920   IN  EFI_HANDLE                        PciHandle,
921   IN  VOID                              **RomImage,
922   OUT UINTN                             *Flags,
923   OUT UINT8                             *DiskStart, OPTIONAL
924   OUT UINT8                             *DiskEnd, OPTIONAL
925   OUT VOID                              **RomShadowAddress, OPTIONAL
926   OUT UINT32                            *RomShadowedSize OPTIONAL
927   );
928 
929 
930 /**
931   Fill in the standard BDA for Keyboard LEDs
932 
933   @param  This                   Protocol instance pointer.
934   @param  Leds                   Current LED status
935 
936   @retval EFI_SUCCESS            It should always work.
937 
938 **/
939 EFI_STATUS
940 EFIAPI
941 LegacyBiosUpdateKeyboardLedStatus (
942   IN EFI_LEGACY_BIOS_PROTOCOL           *This,
943   IN UINT8                              Leds
944   );
945 
946 
947 /**
948   Get all BBS info
949 
950   @param  This                   Protocol instance pointer.
951   @param  HddCount               Number of HDD_INFO structures
952   @param  HddInfo                Onboard IDE controller information
953   @param  BbsCount               Number of BBS_TABLE structures
954   @param  BbsTable               List BBS entries
955 
956   @retval EFI_SUCCESS            Tables returned
957   @retval EFI_NOT_FOUND          resource not found
958   @retval EFI_DEVICE_ERROR       can not get BBS table
959 
960 **/
961 EFI_STATUS
962 EFIAPI
963 LegacyBiosGetBbsInfo (
964   IN  EFI_LEGACY_BIOS_PROTOCOL          *This,
965   OUT UINT16                            *HddCount,
966   OUT HDD_INFO                          **HddInfo,
967   OUT UINT16                            *BbsCount,
968   OUT BBS_TABLE                         **BbsTable
969   );
970 
971 
972 /**
973   Shadow all legacy16 OPROMs that haven't been shadowed.
974   Warning: Use this with caution. This routine disconnects all EFI
975   drivers. If used externally then caller must re-connect EFI
976   drivers.
977 
978   @param  This                   Protocol instance pointer.
979 
980   @retval EFI_SUCCESS            OPROMs shadowed
981 
982 **/
983 EFI_STATUS
984 EFIAPI
985 LegacyBiosShadowAllLegacyOproms (
986   IN EFI_LEGACY_BIOS_PROTOCOL   *This
987   );
988 
989 
990 /**
991   Attempt to legacy boot the BootOption. If the EFI contexted has been
992   compromised this function will not return.
993 
994   @param  This                   Protocol instance pointer.
995   @param  BbsDevicePath          EFI Device Path from BootXXXX variable.
996   @param  LoadOptionsSize        Size of LoadOption in size.
997   @param  LoadOptions            LoadOption from BootXXXX variable
998 
999   @retval EFI_SUCCESS            Removable media not present
1000 
1001 **/
1002 EFI_STATUS
1003 EFIAPI
1004 LegacyBiosLegacyBoot (
1005   IN  EFI_LEGACY_BIOS_PROTOCOL          *This,
1006   IN  BBS_BBS_DEVICE_PATH               *BbsDevicePath,
1007   IN  UINT32                            LoadOptionsSize,
1008   IN  VOID                              *LoadOptions
1009   );
1010 
1011 
1012 /**
1013   Allocate memory < 1 MB and copy the thunker code into low memory. Se up
1014   all the descriptors.
1015 
1016   @param  Private                Private context for Legacy BIOS
1017 
1018   @retval EFI_SUCCESS            Should only pass.
1019 
1020 **/
1021 EFI_STATUS
1022 LegacyBiosInitializeThunk (
1023   IN  LEGACY_BIOS_INSTANCE    *Private
1024   );
1025 
1026 
1027 /**
1028   Fill in the standard BDA and EBDA stuff before Legacy16 load
1029 
1030   @param  Private                Legacy BIOS Instance data
1031 
1032   @retval EFI_SUCCESS            It should always work.
1033 
1034 **/
1035 EFI_STATUS
1036 LegacyBiosInitBda (
1037   IN  LEGACY_BIOS_INSTANCE    *Private
1038   );
1039 
1040 
1041 /**
1042   Collect IDE Inquiry data from the IDE disks
1043 
1044   @param  Private                Legacy BIOS Instance data
1045   @param  HddInfo                Hdd Information
1046   @param  Flag                   Reconnect IdeController or not
1047 
1048   @retval EFI_SUCCESS            It should always work.
1049 
1050 **/
1051 EFI_STATUS
1052 LegacyBiosBuildIdeData (
1053   IN  LEGACY_BIOS_INSTANCE      *Private,
1054   IN  HDD_INFO                  **HddInfo,
1055   IN  UINT16                    Flag
1056   );
1057 
1058 
1059 /**
1060   Enable ide controller.  This gets disabled when LegacyBoot.c is about
1061   to run the Option ROMs.
1062 
1063   @param  Private                Legacy BIOS Instance data
1064 
1065 
1066 **/
1067 VOID
1068 EnableIdeController (
1069   IN LEGACY_BIOS_INSTANCE       *Private
1070   );
1071 
1072 
1073 /**
1074   If the IDE channel is in compatibility (legacy) mode, remove all
1075   PCI I/O BAR addresses from the controller.
1076 
1077   @param  IdeController          The handle of target IDE controller
1078 
1079 
1080 **/
1081 VOID
1082 InitLegacyIdeController (
1083   IN EFI_HANDLE                 IdeController
1084   );
1085 
1086 
1087 /**
1088   Program the interrupt routing register in all the PCI devices. On a PC AT system
1089   this register contains the 8259 IRQ vector that matches it's PCI interrupt.
1090 
1091   @param  Private                Legacy  BIOS Instance data
1092 
1093   @retval EFI_SUCCESS            Succeed.
1094   @retval EFI_ALREADY_STARTED    All PCI devices have been processed.
1095 
1096 **/
1097 EFI_STATUS
1098 PciProgramAllInterruptLineRegisters (
1099   IN  LEGACY_BIOS_INSTANCE      *Private
1100   );
1101 
1102 
1103 /**
1104   Collect EFI Info about legacy devices.
1105 
1106   @param  Private                Legacy BIOS Instance data
1107 
1108   @retval EFI_SUCCESS            It should always work.
1109 
1110 **/
1111 EFI_STATUS
1112 LegacyBiosBuildSioData (
1113   IN  LEGACY_BIOS_INSTANCE      *Private
1114   );
1115 
1116 
1117 /**
1118   Shadow all the PCI legacy ROMs. Use data from the Legacy BIOS Protocol
1119   to chose the order. Skip any devices that have already have legacy
1120   BIOS run.
1121 
1122   @param  Private                Protocol instance pointer.
1123 
1124   @retval EFI_SUCCESS            Succeed.
1125   @retval EFI_UNSUPPORTED        Cannot get VGA device handle.
1126 
1127 **/
1128 EFI_STATUS
1129 PciShadowRoms (
1130   IN  LEGACY_BIOS_INSTANCE      *Private
1131   );
1132 
1133 
1134 /**
1135   Fill in the standard BDA and EBDA stuff prior to legacy Boot
1136 
1137   @param  Private                Legacy BIOS Instance data
1138 
1139   @retval EFI_SUCCESS            It should always work.
1140 
1141 **/
1142 EFI_STATUS
1143 LegacyBiosCompleteBdaBeforeBoot (
1144   IN  LEGACY_BIOS_INSTANCE    *Private
1145   );
1146 
1147 
1148 /**
1149   Fill in the standard CMOS stuff before Legacy16 load
1150 
1151   @param  Private                Legacy BIOS Instance data
1152 
1153   @retval EFI_SUCCESS            It should always work.
1154 
1155 **/
1156 EFI_STATUS
1157 LegacyBiosInitCmos (
1158   IN  LEGACY_BIOS_INSTANCE    *Private
1159   );
1160 
1161 
1162 /**
1163   Fill in the standard CMOS stuff prior to legacy Boot
1164 
1165   @param  Private                Legacy BIOS Instance data
1166 
1167   @retval EFI_SUCCESS            It should always work.
1168 
1169 **/
1170 EFI_STATUS
1171 LegacyBiosCompleteStandardCmosBeforeBoot (
1172   IN  LEGACY_BIOS_INSTANCE    *Private
1173   );
1174 
1175 
1176 /**
1177   Contains the code that is copied into low memory (below 640K).
1178   This code reflects interrupts 0x68-0x6f to interrupts 0x08-0x0f.
1179   This template must be copied into low memory, and the IDT entries
1180   0x68-0x6F must be point to the low memory copy of this code.  Each
1181   entry is 4 bytes long, so IDT entries 0x68-0x6F can be easily
1182   computed.
1183 
1184 **/
1185 VOID
1186 InterruptRedirectionTemplate (
1187   VOID
1188   );
1189 
1190 
1191 /**
1192   Build the E820 table.
1193 
1194   @param  Private                Legacy BIOS Instance data
1195   @param  Size                   Size of E820 Table
1196 
1197   @retval EFI_SUCCESS            It should always work.
1198 
1199 **/
1200 EFI_STATUS
1201 LegacyBiosBuildE820 (
1202   IN  LEGACY_BIOS_INSTANCE    *Private,
1203   OUT UINTN                   *Size
1204   );
1205 
1206 /**
1207   This function is to put all AP in halt state.
1208 
1209   @param  Private                Legacy BIOS Instance data
1210 
1211 **/
1212 VOID
1213 ShutdownAPs (
1214   IN LEGACY_BIOS_INSTANCE              *Private
1215   );
1216 
1217 /**
1218   Worker function for LegacyBiosGetFlatDescs, retrieving content of
1219   specific registers.
1220 
1221   @param  IntThunk  Pointer to IntThunk of Legacy BIOS context.
1222 
1223 **/
1224 VOID
1225 GetRegisters (
1226   LOW_MEMORY_THUNK    *IntThunk
1227   );
1228 
1229 /**
1230   Routine for calling real thunk code.
1231 
1232   @param  RealCode    The address of thunk code.
1233   @param  BiosInt     The Bios interrupt vector number.
1234   @param  CallAddress The address of 16-bit mode call.
1235 
1236   @return  Status returned by real thunk code
1237 
1238 **/
1239 UINTN
1240 CallRealThunkCode (
1241   UINT8               *RealCode,
1242   UINT8               BiosInt,
1243   UINT32              CallAddress
1244   );
1245 
1246 /**
1247   Routine for generating soft interrupt.
1248 
1249   @param Vector  The interrupt vector number.
1250 
1251 **/
1252 VOID
1253 GenerateSoftInit (
1254   UINT8               Vector
1255   );
1256 
1257 /**
1258   Do an AllocatePages () of type AllocateMaxAddress for EfiBootServicesCode
1259   memory.
1260 
1261   @param  AllocateType               Allocated Legacy Memory Type
1262   @param  StartPageAddress           Start address of range
1263   @param  Pages                      Number of pages to allocate
1264   @param  Result                     Result of allocation
1265 
1266   @retval EFI_SUCCESS                Legacy16 code loaded
1267   @retval Other                      No protocol installed, unload driver.
1268 
1269 **/
1270 EFI_STATUS
1271 AllocateLegacyMemory (
1272   IN  EFI_ALLOCATE_TYPE         AllocateType,
1273   IN  EFI_PHYSICAL_ADDRESS      StartPageAddress,
1274   IN  UINTN                     Pages,
1275   OUT EFI_PHYSICAL_ADDRESS      *Result
1276   );
1277 
1278 /**
1279   Get a region from the LegacyBios for Tiano usage. Can only be invoked once.
1280 
1281   @param  This                       Protocol instance pointer.
1282   @param  LegacyMemorySize           Size of required region
1283   @param  Region                     Region to use. 00 = Either 0xE0000 or 0xF0000
1284                                      block Bit0 = 1 0xF0000 block Bit1 = 1 0xE0000
1285                                      block
1286   @param  Alignment                  Address alignment. Bit mapped. First non-zero
1287                                      bit from right is alignment.
1288   @param  LegacyMemoryAddress        Region Assigned
1289 
1290   @retval EFI_SUCCESS                Region assigned
1291   @retval EFI_ACCESS_DENIED          Procedure previously invoked
1292   @retval Other                      Region not assigned
1293 
1294 **/
1295 EFI_STATUS
1296 EFIAPI
1297 LegacyBiosGetLegacyRegion (
1298   IN    EFI_LEGACY_BIOS_PROTOCOL *This,
1299   IN    UINTN                    LegacyMemorySize,
1300   IN    UINTN                    Region,
1301   IN    UINTN                    Alignment,
1302   OUT   VOID                     **LegacyMemoryAddress
1303   );
1304 
1305 /**
1306   Get a region from the LegacyBios for Tiano usage. Can only be invoked once.
1307 
1308   @param  This                       Protocol instance pointer.
1309   @param  LegacyMemorySize           Size of data to copy
1310   @param  LegacyMemoryAddress        Legacy Region destination address Note: must
1311                                      be in region assigned by
1312                                      LegacyBiosGetLegacyRegion
1313   @param  LegacyMemorySourceAddress  Source of data
1314 
1315   @retval EFI_SUCCESS                Region assigned
1316   @retval EFI_ACCESS_DENIED          Destination outside assigned region
1317 
1318 **/
1319 EFI_STATUS
1320 EFIAPI
1321 LegacyBiosCopyLegacyRegion (
1322   IN EFI_LEGACY_BIOS_PROTOCOL *This,
1323   IN    UINTN                 LegacyMemorySize,
1324   IN    VOID                  *LegacyMemoryAddress,
1325   IN    VOID                  *LegacyMemorySourceAddress
1326   );
1327 
1328 /**
1329   Find Legacy16 BIOS image in the FLASH device and shadow it into memory. Find
1330   the $EFI table in the shadow area. Thunk into the Legacy16 code after it had
1331   been shadowed.
1332 
1333   @param  Private                    Legacy BIOS context data
1334 
1335   @retval EFI_SUCCESS                Legacy16 code loaded
1336   @retval Other                      No protocol installed, unload driver.
1337 
1338 **/
1339 EFI_STATUS
1340 ShadowAndStartLegacy16 (
1341   IN  LEGACY_BIOS_INSTANCE  *Private
1342   );
1343 
1344 /**
1345   Checks the state of the floppy and if media is inserted.
1346 
1347   This routine checks the state of the floppy and if media is inserted.
1348   There are 3 cases:
1349   No floppy present         - Set BBS entry to ignore
1350   Floppy present & no media - Set BBS entry to lowest priority. We cannot
1351   set it to ignore since 16-bit CSM will
1352   indicate no floppy and thus drive A: is
1353   unusable. CSM-16 will not try floppy since
1354   lowest priority and thus not incur boot
1355   time penality.
1356   Floppy present & media    - Set BBS entry to some priority.
1357 
1358   @return  State of floppy media
1359 
1360 **/
1361 UINT8
1362 HasMediaInFloppy (
1363   VOID
1364   );
1365 
1366 /**
1367   Identify drive data must be updated to actual parameters before boot.
1368   This requires updating the checksum, if it exists.
1369 
1370   @param  IdentifyDriveData       ATA Identify Data
1371   @param  Checksum                checksum of the ATA Identify Data
1372 
1373   @retval EFI_SUCCESS             checksum calculated
1374   @retval EFI_SECURITY_VIOLATION  IdentifyData invalid
1375 
1376 **/
1377 EFI_STATUS
1378 CalculateIdentifyDriveChecksum (
1379   IN  UINT8     *IdentifyDriveData,
1380   OUT UINT8     *Checksum
1381   );
1382 
1383 /**
1384   Identify drive data must be updated to actual parameters before boot.
1385 
1386   @param  IdentifyDriveData       ATA Identify Data
1387 
1388 **/
1389 VOID
1390 UpdateIdentifyDriveData (
1391   IN  UINT8     *IdentifyDriveData
1392   );
1393 
1394 /**
1395   Complete build of BBS TABLE.
1396 
1397   @param  Private                 Legacy BIOS Instance data
1398   @param  BbsTable                BBS Table passed to 16-bit code
1399 
1400   @retval EFI_SUCCESS             Removable media not present
1401 
1402 **/
1403 EFI_STATUS
1404 LegacyBiosBuildBbs (
1405   IN  LEGACY_BIOS_INSTANCE      *Private,
1406   IN  BBS_TABLE                 *BbsTable
1407   );
1408 
1409 /**
1410   Read CMOS register through index/data port.
1411 
1412   @param[in]  Index   The index of the CMOS register to read.
1413 
1414   @return  The data value from the CMOS register specified by Index.
1415 
1416 **/
1417 UINT8
1418 LegacyReadStandardCmos (
1419   IN UINT8  Index
1420   );
1421 
1422 /**
1423   Write CMOS register through index/data port.
1424 
1425   @param[in]  Index  The index of the CMOS register to write.
1426   @param[in]  Value  The value of CMOS register to write.
1427 
1428   @return  The value written to the CMOS register specified by Index.
1429 
1430 **/
1431 UINT8
1432 LegacyWriteStandardCmos (
1433   IN UINT8  Index,
1434   IN UINT8  Value
1435   );
1436 
1437 /**
1438   Calculate the new standard CMOS checksum and write it.
1439 
1440   @param  Private      Legacy BIOS Instance data
1441 
1442   @retval EFI_SUCCESS  Calculate 16-bit checksum successfully
1443 
1444 **/
1445 EFI_STATUS
1446 LegacyCalculateWriteStandardCmosChecksum (
1447   VOID
1448   );
1449 
1450 /**
1451   Test to see if a legacy PCI ROM exists for this device. Optionally return
1452   the Legacy ROM instance for this PCI device.
1453 
1454   @param[in]  This                   Protocol instance pointer.
1455   @param[in]  PciHandle              The PCI PC-AT OPROM from this devices ROM BAR will be loaded
1456   @param[out] RomImage               Return the legacy PCI ROM for this device
1457   @param[out] RomSize                Size of ROM Image
1458   @param[out] RuntimeImageLength     Runtime size of ROM Image
1459   @param[out] Flags                  Indicates if ROM found and if PC-AT.
1460   @param[out] OpromRevision          Revision of the PCI Rom
1461   @param[out] ConfigUtilityCodeHeaderPointer of Configuration Utility Code Header
1462 
1463   @return EFI_SUCCESS            Legacy Option ROM availible for this device
1464   @return EFI_ALREADY_STARTED    This device is already managed by its Oprom
1465   @return EFI_UNSUPPORTED        Legacy Option ROM not supported.
1466 
1467 **/
1468 EFI_STATUS
1469 LegacyBiosCheckPciRomEx (
1470   IN EFI_LEGACY_BIOS_PROTOCOL           *This,
1471   IN  EFI_HANDLE                        PciHandle,
1472   OUT VOID                              **RomImage, OPTIONAL
1473   OUT UINTN                             *RomSize, OPTIONAL
1474   OUT UINTN                             *RuntimeImageLength, OPTIONAL
1475   OUT UINTN                             *Flags, OPTIONAL
1476   OUT UINT8                             *OpromRevision, OPTIONAL
1477   OUT VOID                              **ConfigUtilityCodeHeader OPTIONAL
1478   );
1479 
1480 /**
1481   Relocate this image under 4G memory for IPF.
1482 
1483   @param  ImageHandle  Handle of driver image.
1484   @param  SystemTable  Pointer to system table.
1485 
1486   @retval EFI_SUCCESS  Image successfully relocated.
1487   @retval EFI_ABORTED  Failed to relocate image.
1488 
1489 **/
1490 EFI_STATUS
1491 RelocateImageUnder4GIfNeeded (
1492   IN EFI_HANDLE           ImageHandle,
1493   IN EFI_SYSTEM_TABLE     *SystemTable
1494   );
1495 
1496 /**
1497   Thunk to 16-bit real mode and call Segment:Offset. Regs will contain the
1498   16-bit register context on entry and exit. Arguments can be passed on
1499   the Stack argument
1500 
1501   @param  This       Protocol instance pointer.
1502   @param  Segment    Segemnt of 16-bit mode call
1503   @param  Offset     Offset of 16-bit mdoe call
1504   @param  Regs       Register contexted passed into (and returned) from thunk to
1505                      16-bit mode
1506   @param  Stack      Caller allocated stack used to pass arguments
1507   @param  StackSize  Size of Stack in bytes
1508 
1509   @retval FALSE      Thunk completed, and there were no BIOS errors in the target code.
1510                      See Regs for status.
1511   @retval TRUE       There was a BIOS erro in the target code.
1512 
1513 **/
1514 BOOLEAN
1515 EFIAPI
1516 InternalLegacyBiosFarCall (
1517   IN  EFI_LEGACY_BIOS_PROTOCOL        *This,
1518   IN  UINT16                          Segment,
1519   IN  UINT16                          Offset,
1520   IN  EFI_IA32_REGISTER_SET           *Regs,
1521   IN  VOID                            *Stack,
1522   IN  UINTN                           StackSize
1523   );
1524 
1525 /**
1526   Load a legacy PC-AT OpROM for VGA controller.
1527 
1528   @param  Private                Driver private data.
1529 
1530   @retval EFI_SUCCESS            Legacy ROM successfully installed for this device.
1531   @retval EFI_DEVICE_ERROR       No VGA device handle found, or native EFI video
1532                                  driver cannot be successfully disconnected, or VGA
1533                                  thunk driver cannot be successfully connected.
1534 
1535 **/
1536 EFI_STATUS
1537 LegacyBiosInstallVgaRom (
1538   IN  LEGACY_BIOS_INSTANCE            *Private
1539   );
1540 
1541 #endif
1542