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