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