Home | History | Annotate | Download | only in LegacyBiosDxe
      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